You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Pierre Grenon <pg...@horizon-asset.co.uk> on 2019/05/15 10:56:59 UTC

Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Hello, 

Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?

Example: 

Assume a KB of conferences with their deadlines as xsd:dateTime. 

Here are examples of SPARQL queries to find conferences whose deadlines are passed:

SELECT * WHERE { 
	?subject here:hasDeadline ?date . 
	BIND((xsd:dateTime(?date) - now()) AS ?Span)
	FILTER(?Span < "P0D"^^xsd:duration)
	} 

SELECT * WHERE { 
	?subject here:hasDeadline ?date . 
    	FILTER(now() > xsd:dateTime(?date)) 
	}

Suppose instead I wanted to infer some attribute of the conference, e.g: 

?subject here:hasStatus here:DeadlinePassed 

I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes). 

There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples. 

Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.

https://jena.apache.org/documentation/inference/#rules


With many thanks and kind regards, 
Pierre

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.



RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
Thank you, Dave – I am yet to struggle with this. Hope to be in a position to follow up

Best
Pierre

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.


From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
Sent: 17 May 2019 09:01
To: users@jena.apache.org
Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Hi Pierre,

I can't offer to hold you by the hand I'm afraid, snowed under with
work. But a minimal example might help. Here's an example of a minimal
extension builtin:

class StringEqualIgnoreCase extends BaseBuiltin implements Builtin {

public String getName() {
return "stringEqualIgnoreCase";
}

@Override
public int getArgLength() {
return 2;
}

@Override
public boolean bodyCall(Node[] args, int length, RuleContext context) {
checkArgs(length, context);
Node n1 = getArg(0, args, context);
Node n2 = getArg(1, args, context);
if (n1.isLiteral() && n1.isLiteral()) {
return n1.getLiteralLexicalForm().equalsIgnoreCase(
n2.getLiteralLexicalForm() );
} else {
return false;
}
}

}

and an example driver class for demonstrating it operating:

/**
* Rule test.
*/
public void testRuleSet2() {
String NS = "http://ont.com/<http://ont.com/>";
BuiltinRegistry.theRegistry.register( new
StringEqualIgnoreCase() );
String rules = "[r1: (?x ns:p ?pl) (?x ns:q ?ql)
stringEqualIgnoreCase(?pl, ?ql) -> (?x ns:r 'equal') ]";
Model m = ModelFactory.createDefaultModel();
Resource a = m.createResource(NS + "a");
Resource b = m.createResource(NS + "b");
Property p = m.createProperty(NS + "p");
Property q = m.createProperty(NS + "q");
m.add(a, p, "FOO");
m.add(a, q, "foo");
m.add(b, p, "FOO");
m.add(b, q, "foobar");
GenericRuleReasoner reasoner = new GenericRuleReasoner(Rule
.parseRules(rules));
InfModel infModel = ModelFactory.createInfModel(reasoner, m);
infModel.write(System.out, "Turtle");
}

These are cut/paste from some very ancient examples but hopefully should
work, if not let us know I can see about assembling it into a self
contained working example.

As it says in the documentation, for examples of how to write particular
sorts of builtin then the best place is to look is the source code for
the current builtins.

Dave

On 17/05/2019 07:53, Pierre Grenon wrote:
> Hi
>
> Thanks again.
>
> Hear you.
>
> I think this is becoming a bit too meta perhaps. Maybe there’s a couple of ways to go forward.
>
>
> a. Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me.
>
> b. I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?
>
> Give a shout.
>
> Thanks,
> Pierre
>
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 17 May 2019 07:24
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>
> Hi,
>
>> Hi Lorenz,
>>
>> Thank you for your answer.
>>
>> Quick follow up.
>>
>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
> I can see that it might be too abstract for people coming from different
> areas, sure. But, the question is who is able to provide such a tutorial
> and also who has the time. It's always a trade-off in Open Source
> projects like Jena - I guess most of the devs or other project related
> people here are not getting payed, and clearly such a tutorial for most
> if not all of the built-ins definitely needs some effort. Ideally, the
> community could take over those things, but looks like nobody ever wrote
> blog posts or tutorials about the Jena rule system and its built-ins.
>>
>>
>>
>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
> I don't think you can use functions or expressions from the SPARQL
> engine resp. its XPath constructors. Both are totally different
> implementations I guess - but again, I'm not a developer, so I can't
> make a valid statement, except for looking into the code and the docs.
> From my point of view, only the mentioned built-ins from the docs are
> valid so far.
>>
>>
>>
>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>
>> What’s wrong with :
>>
>>
>>
>> [ruleMissedDeadline2:
>>
>> (?conference ns:hasDeadline ?date)
>>
>> now(?now)
>>
>> greaterThan(?now, ?date)
>>
>> ->
>>
>> (?conference ns:status ns:DeadlinePassed)
>>
>> ]
>
> Well I was clearly thinking too complicated, so yes, your rule should
> work given that the docs say
>
>> lessThan(?x, ?y), greaterThan(?x, ?y)
>> le(?x, ?y), ge(?x, ?y)
>>
>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>> or time instants (can be integer or floating point or XSDDateTime).
> I was more thinking about things like inferring the age of a person
> isn't possible right now, but would clearly be some nice to have feature
> such that you could have it as implicit fact in your KB without the need
> to change the asserted data every year.
>
>>
>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
>
> That's also something I can't answer properly. I mean, yes, you can
> create custom built-ins and register those or maybe create an overriding
> registry [1] ? But not sure, it looks like at least the overriding
> registry would have to be used by the rule parser, so I don't know how
> you would have to combine it with Fuseki. And in the end, yes, you have
> to repackage Fuseki I think as long as you modify the existing
> BuiltinRegistry.
>
> Maybe there is also some other kind of plugin system here, but that can
> only be answered by Andy, Dave, Adam, etc.
>
>
> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204><https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>>
>
>>
>> Many thanks,
>> Pierre
>>
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 16 May 2019 08:33
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> I'm not aware of any tutorial, but afaik you can't do what you did here
>> with SPARQL in Jena rules without writing custom built-ins or by
>> extending the existing ones because:
>>
>> * the "difference" built-in does only work for numbers right now [1]
>>
>> * there is no support for duration type at all it looks like
>>
>>
>> So, so far you could only compare datetime values via lessThan, le,
>> greaterThan, ge but there is no other built-in with support for date
>> values so far. Others might indeed correct me if I'm wrong of.
>>
>>
>> It looks like, you have to extend the rule system by custom built-ins -
>> it's not that difficult though [2]
>>
>> [1]
>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>>
>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>>
>>
>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>
>>> Example:
>>>
>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>
>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>> FILTER(?Span < "P0D"^^xsd:duration)
>>> }
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> FILTER(now() > xsd:dateTime(?date))
>>> }
>>>
>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>
>>> ?subject here:hasStatus here:DeadlinePassed
>>>
>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>
>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>
>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>
>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>>
>>>
>>>
>>> With many thanks and kind regards,
>>> Pierre
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>><http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>>> - semantic web research center
>>
>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>
>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html><https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>>)
>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/><https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>>.
>>
>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>> - semantic web research center
>
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>.
>
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
>
>

Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Dave Reynolds <da...@gmail.com>.
On 03/06/2019 16:36, Pierre Grenon wrote:
> So can I just edit
> 
> \jena-core\src\main\java\org\apache\jena\reasoner\rulesys\ BuiltinRegistry.java
> 
> ?
> 
> Or is that too hackish?

Definitely too hackish.

After some google searching it I see some old mentions that fuseki 
loadClass will call any public static void init() method on the class 
you load. If that's still true then you should be able to put the

BuiltinRegistry.theRegistry.register(...)

call(s) in such an init method.

Dave

> Thanks ,
> Pierre
> 
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
> 
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
> 
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
> 
> 
> From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
> Sent: 03 June 2019 11:17
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
> 
> Hi Pierre,
> 
> I'm afraid I've lost track of what you are tying to do. Originally it
> seemed to be a problem running comparisons on date time values but
> Lorenz has already answered that.
> 
> In terms on writing your own new Builtins, then before you can use a new
> rule Builtin it needs to be registered. That's what the line:
> 
> BuiltinRegistry.theRegistry.register( new StringEqualIgnoreCase() )
> 
> was doing in my (non-fuseki) example.
> 
> If you need your new builtin to run within fuseki then you would need
> some way to trigger such registration code. No doubt that's possible but
> not something I've any first hand knowledge of.
> 
> By the way, for simply getting code loaded into fuseki you don't need to
> repack the jar. Just add your new jar to the classpath and use the
> ja:loadClass function to get your class loaded when fuseki starts up.
> See last example in:
> 
> https://jena.apache.org/documentation/fuseki2/fuseki-configuration.html
> 
> Dave
> 
> On 03/06/2019 07:01, Pierre Grenon wrote:
>> Hi Dave,
>>
>> Executive summary:
>>
>> I'm not a java coder. I did what I could to try to do this using fuseki.
>>
>> I get this:
>> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
>>
>> I understand this may be related to RuleContext. I don't understand any further.
>> Details below.
>>
>> With many thanks,
>> Pierre
>>
>> Details ---
>>
>> 1. I unzipped my fuseki-server.jar
>>
>> 2. I placed the code below into a ..\rulesys\testBuilt.java as
>>
>> <BEGIN CODE>
>> package org.apache.jena.reasoner.rulesys.builtins;
>>
>>
>> import org.apache.jena.graph.* ;
>> import org.apache.jena.reasoner.rulesys.* ;
>>
>> /**
>> * Tests if the first argument is less than the second.
>> */
>>
>> class testBuilt extends BaseBuiltin implements Builtin {
>> public String getName() {
>> return "testBuilt";
>> }
>>
>> @Override
>> public int getArgLength() {
>> return 2;
>> }
>>
>> @Override
>> public boolean bodyCall(Node[] args, int length, RuleContext context) {
>> checkArgs(length, context);
>> Node n1 = getArg(0, args, context);
>> Node n2 = getArg(1, args, context);
>> if (n1.isLiteral() && n1.isLiteral()) {
>> return n1.getLiteralLexicalForm().equalsIgnoreCase(
>> n2.getLiteralLexicalForm() );
>> } else {
>> return false;
>> }
>> }
>> }
>>
>> <END CODE>
>>
>> 3. Compiled that:
>>
>> C:\dev\apache-jena-fuseki-3.10.0\woot>javac org\apache\jena\reasoner\rulesys\builtins\testBuilt.java
>>
>> 4. Jar-ed the whole thing back
>>
>> C:\dev\apache-jena-fuseki-3.10.0\woot>jar cmvf fuseki-server\META-INF\MANIFEST.MF fuseki-server.jar -C fuseki-server/ .
>>
>> 5. Replaced my fuseki-server.jar
>>
>> 6. Created a rule file
>>
>> <BEGIN RULE FILE>
>> @prefix ns: <http://test.org#> .
>> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
>> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
>>
>> [r1:
>> (?x ns:p ?pl)
>> (?x ns:q ?ql)
>> testBuilt(?pl, ?ql)
>> ->
>> (?x ns:r 'equal')
>> ]
>> <END RULE FILE>
>>
>> 7. Created a dataset file
>>
>> <BEGIN DATASET FILE>
>> @prefix ns: <http://test.org#> .
>> @prefix owl: <http://www.w3.org/2002/07/owl#> .
>> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
>> @prefix xml: <http://www.w3.org/XML/1998/namespace> .
>> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
>> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
>>
>> <http://test.org#Conference0> ns:p "PenguiN" .
>> <http://test.org#Conference0> ns:q "penguin" .
>> <http://test.org#Conference1> ns:p "penguin" .
>> <http://test.org#Conference1> ns:q "penGuin" .
>> <http://test.org#Conference2> ns:p "Penguin" .
>> <http://test.org#Conference2> ns:q "penguin" .
>> <http://test.org#Workshop1> ns:p "Noot" .
>> <http://test.org#Workshop1> ns:q "noot" .
>> <http://test.org#Workshop2> ns:p "NootNoot" .
>> <http://test.org#Workshop2> ns:q "nootNoot" .
>>
>> <END DATASET FILE>
>>
>>
>> 8. Created a config file on the previous model to use the above
>>
>> <BEGIN CONFIG FILE>
>> @prefix : <http://base/#> .
>> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
>> @prefix tdb2: <http://jena.apache.org/2016/tdb#> .
>> @prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
>> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
>> @prefix fuseki: <http://jena.apache.org/fuseki#> .
>>
>> :theServiceBI a fuseki:Service ;
>> rdfs:label "Service with update and query to test minimal dataset with custom built-in inference using an instance of generic rule reasoner" ;
>> fuseki:dataset :theDatasetBI ;
>> #:tdb_dataset_readwrite ;
>> fuseki:name "ConferenceBuiltIn" ;
>> fuseki:serviceQuery "query" , "sparql" ;
>> fuseki:serviceReadGraphStore "get" ;
>> fuseki:serviceReadWriteGraphStore
>> "data" ;
>> fuseki:serviceUpdate "update" ;
>> fuseki:serviceUpload "upload" .
>>
>> :theDatasetBI a ja:RDFDataset ;
>> ja:defaultGraph <#theModel_GRRBI> .
>>
>> <#theModel_GRRBI> a ja:InfModel ;
>> ja:baseModel <#theGraphBI> ;
>> ja:reasoner [
>> ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
>> ja:rulesFrom <file:///C:/dev/apache-jena-fuseki-3.10.0/data/conference/conference2.rules>
>> ] ;
>> .
>>
>> <#theGraphBI> rdf:type tdb2:GraphTDB ;
>> tdb2:dataset :theTDB2DatasetBI .
>>
>> :theTDB2DatasetBI
>> a tdb2:DatasetTDB2 ;
>> tdb2:location "C:\\dev\\apache-jena-fuseki-3.10.0\\run/databases/ConferenceBuiltIn" ;
>> tdb2:unionDefaultGraph true.
>>
>> <END CONFIG FILE>
>>
>> This is my query:
>> -----------------------
>>
>> prefix ns: <http://test.org#>
>> select *
>> where
>> {?x ns:r ?z}
>> limit 5
>>
>> This is Fuskei's log:
>> --------------------------
>>
>> [2019-05-31 18:47:22] Server INFO Started 2019/05/31 18:47:22 BST on port 3030
>> [2019-05-31 18:47:30] Fuseki INFO [1] POST http://localhost:3030/ConferenceBuiltIn/sparql
>> [2019-05-31 18:47:30] Fuseki INFO [1] Query = prefix ns: <http://test.org#> select * where {?x ns:r ?z} limit 5
>> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
>> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
>> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
>> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
>> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
>> [2019-05-31 18:47:30] Fuseki INFO [1] 200 OK (78 ms)
>>
>> ###### END OF MESSAGE
>>
>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>
>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
>>
>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>
>>
>> From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
>> Sent: 17 May 2019 09:01
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> Hi Pierre,
>>
>> I can't offer to hold you by the hand I'm afraid, snowed under with
>> work. But a minimal example might help. Here's an example of a minimal
>> extension builtin:
>>
>> class StringEqualIgnoreCase extends BaseBuiltin implements Builtin {
>>
>> public String getName() {
>> return "stringEqualIgnoreCase";
>> }
>>
>> @Override
>> public int getArgLength() {
>> return 2;
>> }
>>
>> @Override
>> public boolean bodyCall(Node[] args, int length, RuleContext context) {
>> checkArgs(length, context);
>> Node n1 = getArg(0, args, context);
>> Node n2 = getArg(1, args, context);
>> if (n1.isLiteral() && n1.isLiteral()) {
>> return n1.getLiteralLexicalForm().equalsIgnoreCase(
>> n2.getLiteralLexicalForm() );
>> } else {
>> return false;
>> }
>> }
>>
>> }
>>
>> and an example driver class for demonstrating it operating:
>>
>> /**
>> * Rule test.
>> */
>> public void testRuleSet2() {
>> String NS = "http://ont.com/";
>> BuiltinRegistry.theRegistry.register( new
>> StringEqualIgnoreCase() );
>> String rules = "[r1: (?x ns:p ?pl) (?x ns:q ?ql)
>> stringEqualIgnoreCase(?pl, ?ql) -> (?x ns:r 'equal') ]";
>> Model m = ModelFactory.createDefaultModel();
>> Resource a = m.createResource(NS + "a");
>> Resource b = m.createResource(NS + "b");
>> Property p = m.createProperty(NS + "p");
>> Property q = m.createProperty(NS + "q");
>> m.add(a, p, "FOO");
>> m.add(a, q, "foo");
>> m.add(b, p, "FOO");
>> m.add(b, q, "foobar");
>> GenericRuleReasoner reasoner = new GenericRuleReasoner(Rule
>> .parseRules(rules));
>> InfModel infModel = ModelFactory.createInfModel(reasoner, m);
>> infModel.write(System.out, "Turtle");
>> }
>>
>> These are cut/paste from some very ancient examples but hopefully should
>> work, if not let us know I can see about assembling it into a self
>> contained working example.
>>
>> As it says in the documentation, for examples of how to write particular
>> sorts of builtin then the best place is to look is the source code for
>> the current builtins.
>>
>> Dave
>>
>> On 17/05/2019 07:53, Pierre Grenon wrote:
>>> Hi
>>>
>>> Thanks again.
>>>
>>> Hear you.
>>>
>>> I think this is becoming a bit too meta perhaps. Maybe there’s a couple of ways to go forward.
>>>
>>>
>>> a. Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me.
>>>
>>> b. I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?
>>>
>>> Give a shout.
>>>
>>> Thanks,
>>> Pierre
>>>
>>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>>> Sent: 17 May 2019 07:24
>>> To: users@jena.apache.org
>>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>>
>>> Hi,
>>>
>>>> Hi Lorenz,
>>>>
>>>> Thank you for your answer.
>>>>
>>>> Quick follow up.
>>>>
>>>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
>>> I can see that it might be too abstract for people coming from different
>>> areas, sure. But, the question is who is able to provide such a tutorial
>>> and also who has the time. It's always a trade-off in Open Source
>>> projects like Jena - I guess most of the devs or other project related
>>> people here are not getting payed, and clearly such a tutorial for most
>>> if not all of the built-ins definitely needs some effort. Ideally, the
>>> community could take over those things, but looks like nobody ever wrote
>>> blog posts or tutorials about the Jena rule system and its built-ins.
>>>>
>>>>
>>>>
>>>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
>>> I don't think you can use functions or expressions from the SPARQL
>>> engine resp. its XPath constructors. Both are totally different
>>> implementations I guess - but again, I'm not a developer, so I can't
>>> make a valid statement, except for looking into the code and the docs.
>>>  From my point of view, only the mentioned built-ins from the docs are
>>> valid so far.
>>>>
>>>>
>>>>
>>>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>>>
>>>> What’s wrong with :
>>>>
>>>>
>>>>
>>>> [ruleMissedDeadline2:
>>>>
>>>> (?conference ns:hasDeadline ?date)
>>>>
>>>> now(?now)
>>>>
>>>> greaterThan(?now, ?date)
>>>>
>>>> ->
>>>>
>>>> (?conference ns:status ns:DeadlinePassed)
>>>>
>>>> ]
>>>
>>> Well I was clearly thinking too complicated, so yes, your rule should
>>> work given that the docs say
>>>
>>>> lessThan(?x, ?y), greaterThan(?x, ?y)
>>>> le(?x, ?y), ge(?x, ?y)
>>>>
>>>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>>>> or time instants (can be integer or floating point or XSDDateTime).
>>> I was more thinking about things like inferring the age of a person
>>> isn't possible right now, but would clearly be some nice to have feature
>>> such that you could have it as implicit fact in your KB without the need
>>> to change the asserted data every year.
>>>
>>>>
>>>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
>>>
>>> That's also something I can't answer properly. I mean, yes, you can
>>> create custom built-ins and register those or maybe create an overriding
>>> registry [1] ? But not sure, it looks like at least the overriding
>>> registry would have to be used by the rule parser, so I don't know how
>>> you would have to combine it with Fuseki. And in the end, yes, you have
>>> to repackage Fuseki I think as long as you modify the existing
>>> BuiltinRegistry.
>>>
>>> Maybe there is also some other kind of plugin system here, but that can
>>> only be answered by Andy, Dave, Adam, etc.
>>>
>>>
>>> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>
>>>
>>>>
>>>> Many thanks,
>>>> Pierre
>>>>
>>>>
>>>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>>>> Sent: 16 May 2019 08:33
>>>> To: users@jena.apache.org
>>>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>>>
>>>> I'm not aware of any tutorial, but afaik you can't do what you did here
>>>> with SPARQL in Jena rules without writing custom built-ins or by
>>>> extending the existing ones because:
>>>>
>>>> * the "difference" built-in does only work for numbers right now [1]
>>>>
>>>> * there is no support for duration type at all it looks like
>>>>
>>>>
>>>> So, so far you could only compare datetime values via lessThan, le,
>>>> greaterThan, ge but there is no other built-in with support for date
>>>> values so far. Others might indeed correct me if I'm wrong of.
>>>>
>>>>
>>>> It looks like, you have to extend the rule system by custom built-ins -
>>>> it's not that difficult though [2]
>>>>
>>>> [1]
>>>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
>>>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>>>>
>>>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>>>
>>>>> Example:
>>>>>
>>>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>>>
>>>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>>>
>>>>> SELECT * WHERE {
>>>>> ?subject here:hasDeadline ?date .
>>>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>>>> FILTER(?Span < "P0D"^^xsd:duration)
>>>>> }
>>>>>
>>>>> SELECT * WHERE {
>>>>> ?subject here:hasDeadline ?date .
>>>>> FILTER(now() > xsd:dateTime(?date))
>>>>> }
>>>>>
>>>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>>>
>>>>> ?subject here:hasStatus here:DeadlinePassed
>>>>>
>>>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>>>
>>>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>>>
>>>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>>>
>>>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>>>>
>>>>>

RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
So can I just edit 

\jena-core\src\main\java\org\apache\jena\reasoner\rulesys\ BuiltinRegistry.java

?

Or is that too hackish?

Thanks , 
Pierre

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.


From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com] 
Sent: 03 June 2019 11:17
To: users@jena.apache.org
Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Hi Pierre,

I'm afraid I've lost track of what you are tying to do. Originally it 
seemed to be a problem running comparisons on date time values but 
Lorenz has already answered that.

In terms on writing your own new Builtins, then before you can use a new 
rule Builtin it needs to be registered. That's what the line:

BuiltinRegistry.theRegistry.register( new StringEqualIgnoreCase() )

was doing in my (non-fuseki) example.

If you need your new builtin to run within fuseki then you would need 
some way to trigger such registration code. No doubt that's possible but 
not something I've any first hand knowledge of.

By the way, for simply getting code loaded into fuseki you don't need to 
repack the jar. Just add your new jar to the classpath and use the 
ja:loadClass function to get your class loaded when fuseki starts up. 
See last example in:

https://jena.apache.org/documentation/fuseki2/fuseki-configuration.html

Dave

On 03/06/2019 07:01, Pierre Grenon wrote:
> Hi Dave,
> 
> Executive summary:
> 
> I'm not a java coder. I did what I could to try to do this using fuseki.
> 
> I get this:
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> 
> I understand this may be related to RuleContext. I don't understand any further.
> Details below.
> 
> With many thanks,
> Pierre
> 
> Details ---
> 
> 1. I unzipped my fuseki-server.jar
> 
> 2. I placed the code below into a ..\rulesys\testBuilt.java as
> 
> <BEGIN CODE>
> package org.apache.jena.reasoner.rulesys.builtins;
> 
> 
> import org.apache.jena.graph.* ;
> import org.apache.jena.reasoner.rulesys.* ;
> 
> /**
> * Tests if the first argument is less than the second.
> */
> 
> class testBuilt extends BaseBuiltin implements Builtin {
> public String getName() {
> return "testBuilt";
> }
> 
> @Override
> public int getArgLength() {
> return 2;
> }
> 
> @Override
> public boolean bodyCall(Node[] args, int length, RuleContext context) {
> checkArgs(length, context);
> Node n1 = getArg(0, args, context);
> Node n2 = getArg(1, args, context);
> if (n1.isLiteral() && n1.isLiteral()) {
> return n1.getLiteralLexicalForm().equalsIgnoreCase(
> n2.getLiteralLexicalForm() );
> } else {
> return false;
> }
> }
> }
> 
> <END CODE> 
> 
> 3. Compiled that:
> 
> C:\dev\apache-jena-fuseki-3.10.0\woot>javac org\apache\jena\reasoner\rulesys\builtins\testBuilt.java
> 
> 4. Jar-ed the whole thing back
> 
> C:\dev\apache-jena-fuseki-3.10.0\woot>jar cmvf fuseki-server\META-INF\MANIFEST.MF fuseki-server.jar -C fuseki-server/ .
> 
> 5. Replaced my fuseki-server.jar
> 
> 6. Created a rule file
> 
> <BEGIN RULE FILE>
> @prefix ns: <http://test.org#> .
> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> 
> [r1:
> (?x ns:p ?pl)
> (?x ns:q ?ql)
> testBuilt(?pl, ?ql)
> ->
> (?x ns:r 'equal')
> ]
> <END RULE FILE>
> 
> 7. Created a dataset file
> 
> <BEGIN DATASET FILE>
> @prefix ns: <http://test.org#> .
> @prefix owl: <http://www.w3.org/2002/07/owl#> .
> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix xml: <http://www.w3.org/XML/1998/namespace> .
> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> 
> <http://test.org#Conference0> ns:p "PenguiN" .
> <http://test.org#Conference0> ns:q "penguin" .
> <http://test.org#Conference1> ns:p "penguin" .
> <http://test.org#Conference1> ns:q "penGuin" .
> <http://test.org#Conference2> ns:p "Penguin" .
> <http://test.org#Conference2> ns:q "penguin" .
> <http://test.org#Workshop1> ns:p "Noot" .
> <http://test.org#Workshop1> ns:q "noot" .
> <http://test.org#Workshop2> ns:p "NootNoot" .
> <http://test.org#Workshop2> ns:q "nootNoot" .
> 
> <END DATASET FILE>
> 
> 
> 8. Created a config file on the previous model to use the above
> 
> <BEGIN CONFIG FILE>
> @prefix : <http://base/#> .
> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix tdb2: <http://jena.apache.org/2016/tdb#> .
> @prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> @prefix fuseki: <http://jena.apache.org/fuseki#> .
> 
> :theServiceBI a fuseki:Service ;
> rdfs:label "Service with update and query to test minimal dataset with custom built-in inference using an instance of generic rule reasoner" ;
> fuseki:dataset :theDatasetBI ;
> #:tdb_dataset_readwrite ;
> fuseki:name "ConferenceBuiltIn" ;
> fuseki:serviceQuery "query" , "sparql" ;
> fuseki:serviceReadGraphStore "get" ;
> fuseki:serviceReadWriteGraphStore
> "data" ;
> fuseki:serviceUpdate "update" ;
> fuseki:serviceUpload "upload" .
> 
> :theDatasetBI a ja:RDFDataset ;
> ja:defaultGraph <#theModel_GRRBI> .
> 
> <#theModel_GRRBI> a ja:InfModel ;
> ja:baseModel <#theGraphBI> ;
> ja:reasoner [
> ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
> ja:rulesFrom <file:///C:/dev/apache-jena-fuseki-3.10.0/data/conference/conference2.rules>
> ] ;
> .
> 
> <#theGraphBI> rdf:type tdb2:GraphTDB ;
> tdb2:dataset :theTDB2DatasetBI .
> 
> :theTDB2DatasetBI
> a tdb2:DatasetTDB2 ;
> tdb2:location "C:\\dev\\apache-jena-fuseki-3.10.0\\run/databases/ConferenceBuiltIn" ;
> tdb2:unionDefaultGraph true.
> 
> <END CONFIG FILE>
> 
> This is my query:
> -----------------------
> 
> prefix ns: <http://test.org#>
> select *
> where
> {?x ns:r ?z}
> limit 5
> 
> This is Fuskei's log:
> --------------------------
> 
> [2019-05-31 18:47:22] Server INFO Started 2019/05/31 18:47:22 BST on port 3030
> [2019-05-31 18:47:30] Fuseki INFO [1] POST http://localhost:3030/ConferenceBuiltIn/sparql
> [2019-05-31 18:47:30] Fuseki INFO [1] Query = prefix ns: <http://test.org#> select * where {?x ns:r ?z} limit 5
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Fuseki INFO [1] 200 OK (78 ms)
> 
> ###### END OF MESSAGE
> 
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
> 
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
> 
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
> 
> 
> From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
> Sent: 17 May 2019 09:01
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
> 
> Hi Pierre,
> 
> I can't offer to hold you by the hand I'm afraid, snowed under with
> work. But a minimal example might help. Here's an example of a minimal
> extension builtin:
> 
> class StringEqualIgnoreCase extends BaseBuiltin implements Builtin {
> 
> public String getName() {
> return "stringEqualIgnoreCase";
> }
> 
> @Override
> public int getArgLength() {
> return 2;
> }
> 
> @Override
> public boolean bodyCall(Node[] args, int length, RuleContext context) {
> checkArgs(length, context);
> Node n1 = getArg(0, args, context);
> Node n2 = getArg(1, args, context);
> if (n1.isLiteral() && n1.isLiteral()) {
> return n1.getLiteralLexicalForm().equalsIgnoreCase(
> n2.getLiteralLexicalForm() );
> } else {
> return false;
> }
> }
> 
> }
> 
> and an example driver class for demonstrating it operating:
> 
> /**
> * Rule test.
> */
> public void testRuleSet2() {
> String NS = "http://ont.com/";
> BuiltinRegistry.theRegistry.register( new
> StringEqualIgnoreCase() );
> String rules = "[r1: (?x ns:p ?pl) (?x ns:q ?ql)
> stringEqualIgnoreCase(?pl, ?ql) -> (?x ns:r 'equal') ]";
> Model m = ModelFactory.createDefaultModel();
> Resource a = m.createResource(NS + "a");
> Resource b = m.createResource(NS + "b");
> Property p = m.createProperty(NS + "p");
> Property q = m.createProperty(NS + "q");
> m.add(a, p, "FOO");
> m.add(a, q, "foo");
> m.add(b, p, "FOO");
> m.add(b, q, "foobar");
> GenericRuleReasoner reasoner = new GenericRuleReasoner(Rule
> .parseRules(rules));
> InfModel infModel = ModelFactory.createInfModel(reasoner, m);
> infModel.write(System.out, "Turtle");
> }
> 
> These are cut/paste from some very ancient examples but hopefully should
> work, if not let us know I can see about assembling it into a self
> contained working example.
> 
> As it says in the documentation, for examples of how to write particular
> sorts of builtin then the best place is to look is the source code for
> the current builtins.
> 
> Dave
> 
> On 17/05/2019 07:53, Pierre Grenon wrote:
>> Hi
>>
>> Thanks again.
>>
>> Hear you.
>>
>> I think this is becoming a bit too meta perhaps. Maybe there’s a couple of ways to go forward.
>>
>>
>> a. Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me.
>>
>> b. I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?
>>
>> Give a shout.
>>
>> Thanks,
>> Pierre
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 17 May 2019 07:24
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> Hi,
>>
>>> Hi Lorenz,
>>>
>>> Thank you for your answer.
>>>
>>> Quick follow up.
>>>
>>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
>> I can see that it might be too abstract for people coming from different
>> areas, sure. But, the question is who is able to provide such a tutorial
>> and also who has the time. It's always a trade-off in Open Source
>> projects like Jena - I guess most of the devs or other project related
>> people here are not getting payed, and clearly such a tutorial for most
>> if not all of the built-ins definitely needs some effort. Ideally, the
>> community could take over those things, but looks like nobody ever wrote
>> blog posts or tutorials about the Jena rule system and its built-ins.
>>>
>>>
>>>
>>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
>> I don't think you can use functions or expressions from the SPARQL
>> engine resp. its XPath constructors. Both are totally different
>> implementations I guess - but again, I'm not a developer, so I can't
>> make a valid statement, except for looking into the code and the docs.
>> From my point of view, only the mentioned built-ins from the docs are
>> valid so far.
>>>
>>>
>>>
>>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>>
>>> What’s wrong with :
>>>
>>>
>>>
>>> [ruleMissedDeadline2:
>>>
>>> (?conference ns:hasDeadline ?date)
>>>
>>> now(?now)
>>>
>>> greaterThan(?now, ?date)
>>>
>>> ->
>>>
>>> (?conference ns:status ns:DeadlinePassed)
>>>
>>> ]
>>
>> Well I was clearly thinking too complicated, so yes, your rule should
>> work given that the docs say
>>
>>> lessThan(?x, ?y), greaterThan(?x, ?y)
>>> le(?x, ?y), ge(?x, ?y)
>>>
>>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>>> or time instants (can be integer or floating point or XSDDateTime).
>> I was more thinking about things like inferring the age of a person
>> isn't possible right now, but would clearly be some nice to have feature
>> such that you could have it as implicit fact in your KB without the need
>> to change the asserted data every year.
>>
>>>
>>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
>>
>> That's also something I can't answer properly. I mean, yes, you can
>> create custom built-ins and register those or maybe create an overriding
>> registry [1] ? But not sure, it looks like at least the overriding
>> registry would have to be used by the rule parser, so I don't know how
>> you would have to combine it with Fuseki. And in the end, yes, you have
>> to repackage Fuseki I think as long as you modify the existing
>> BuiltinRegistry.
>>
>> Maybe there is also some other kind of plugin system here, but that can
>> only be answered by Andy, Dave, Adam, etc.
>>
>>
>> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>
>>
>>>
>>> Many thanks,
>>> Pierre
>>>
>>>
>>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>>> Sent: 16 May 2019 08:33
>>> To: users@jena.apache.org
>>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>>
>>> I'm not aware of any tutorial, but afaik you can't do what you did here
>>> with SPARQL in Jena rules without writing custom built-ins or by
>>> extending the existing ones because:
>>>
>>> * the "difference" built-in does only work for numbers right now [1]
>>>
>>> * there is no support for duration type at all it looks like
>>>
>>>
>>> So, so far you could only compare datetime values via lessThan, le,
>>> greaterThan, ge but there is no other built-in with support for date
>>> values so far. Others might indeed correct me if I'm wrong of.
>>>
>>>
>>> It looks like, you have to extend the rule system by custom built-ins -
>>> it's not that difficult though [2]
>>>
>>> [1]
>>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
>>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>>>
>>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>>
>>>> Example:
>>>>
>>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>>
>>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>>
>>>> SELECT * WHERE {
>>>> ?subject here:hasDeadline ?date .
>>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>>> FILTER(?Span < "P0D"^^xsd:duration)
>>>> }
>>>>
>>>> SELECT * WHERE {
>>>> ?subject here:hasDeadline ?date .
>>>> FILTER(now() > xsd:dateTime(?date))
>>>> }
>>>>
>>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>>
>>>> ?subject here:hasStatus here:DeadlinePassed
>>>>
>>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>>
>>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>>
>>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>>
>>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>>>
>>>>

RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
Thanks, Dave.

#### PREAMBLE 

For memory and context -- I am on a quest... it was two-pronged

- Lorenz helped me work out the rule and config using an existing built in. That bit is closed.

- I'm pursuing 

"a.	Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me."

I know you said you didn't have time to do this. I've followed this path using the old example of a built in you gave. So now my roadmap is: 

- get a custom built in to work in fuseki (on now)
- work out built in with dates (cherry on the cake) 

####

So I have to figure: 

- How to register new built in in fuseki (but how does fuseki registers them at all then?). I thought that if I packed the class in the jar it was enough to ensure the registration. I'll start a new thread for this I suppose.

Thank you for the ja:loadClass, I will try this, it should allow making the registration . 

Thank you very much, 
Pierre

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.


From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com] 
Sent: 03 June 2019 11:17
To: users@jena.apache.org
Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Hi Pierre,

I'm afraid I've lost track of what you are tying to do. Originally it 
seemed to be a problem running comparisons on date time values but 
Lorenz has already answered that.

In terms on writing your own new Builtins, then before you can use a new 
rule Builtin it needs to be registered. That's what the line:

BuiltinRegistry.theRegistry.register( new StringEqualIgnoreCase() )

was doing in my (non-fuseki) example.

If you need your new builtin to run within fuseki then you would need 
some way to trigger such registration code. No doubt that's possible but 
not something I've any first hand knowledge of.

By the way, for simply getting code loaded into fuseki you don't need to 
repack the jar. Just add your new jar to the classpath and use the 
ja:loadClass function to get your class loaded when fuseki starts up. 
See last example in:

https://jena.apache.org/documentation/fuseki2/fuseki-configuration.html

Dave

On 03/06/2019 07:01, Pierre Grenon wrote:
> Hi Dave,
> 
> Executive summary:
> 
> I'm not a java coder. I did what I could to try to do this using fuseki.
> 
> I get this:
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> 
> I understand this may be related to RuleContext. I don't understand any further.
> Details below.
> 
> With many thanks,
> Pierre
> 
> Details ---
> 
> 1. I unzipped my fuseki-server.jar
> 
> 2. I placed the code below into a ..\rulesys\testBuilt.java as
> 
> <BEGIN CODE>
> package org.apache.jena.reasoner.rulesys.builtins;
> 
> 
> import org.apache.jena.graph.* ;
> import org.apache.jena.reasoner.rulesys.* ;
> 
> /**
> * Tests if the first argument is less than the second.
> */
> 
> class testBuilt extends BaseBuiltin implements Builtin {
> public String getName() {
> return "testBuilt";
> }
> 
> @Override
> public int getArgLength() {
> return 2;
> }
> 
> @Override
> public boolean bodyCall(Node[] args, int length, RuleContext context) {
> checkArgs(length, context);
> Node n1 = getArg(0, args, context);
> Node n2 = getArg(1, args, context);
> if (n1.isLiteral() && n1.isLiteral()) {
> return n1.getLiteralLexicalForm().equalsIgnoreCase(
> n2.getLiteralLexicalForm() );
> } else {
> return false;
> }
> }
> }
> 
> <END CODE> 
> 
> 3. Compiled that:
> 
> C:\dev\apache-jena-fuseki-3.10.0\woot>javac org\apache\jena\reasoner\rulesys\builtins\testBuilt.java
> 
> 4. Jar-ed the whole thing back
> 
> C:\dev\apache-jena-fuseki-3.10.0\woot>jar cmvf fuseki-server\META-INF\MANIFEST.MF fuseki-server.jar -C fuseki-server/ .
> 
> 5. Replaced my fuseki-server.jar
> 
> 6. Created a rule file
> 
> <BEGIN RULE FILE>
> @prefix ns: <http://test.org#> .
> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> 
> [r1:
> (?x ns:p ?pl)
> (?x ns:q ?ql)
> testBuilt(?pl, ?ql)
> ->
> (?x ns:r 'equal')
> ]
> <END RULE FILE>
> 
> 7. Created a dataset file
> 
> <BEGIN DATASET FILE>
> @prefix ns: <http://test.org#> .
> @prefix owl: <http://www.w3.org/2002/07/owl#> .
> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix xml: <http://www.w3.org/XML/1998/namespace> .
> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> 
> <http://test.org#Conference0> ns:p "PenguiN" .
> <http://test.org#Conference0> ns:q "penguin" .
> <http://test.org#Conference1> ns:p "penguin" .
> <http://test.org#Conference1> ns:q "penGuin" .
> <http://test.org#Conference2> ns:p "Penguin" .
> <http://test.org#Conference2> ns:q "penguin" .
> <http://test.org#Workshop1> ns:p "Noot" .
> <http://test.org#Workshop1> ns:q "noot" .
> <http://test.org#Workshop2> ns:p "NootNoot" .
> <http://test.org#Workshop2> ns:q "nootNoot" .
> 
> <END DATASET FILE>
> 
> 
> 8. Created a config file on the previous model to use the above
> 
> <BEGIN CONFIG FILE>
> @prefix : <http://base/#> .
> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix tdb2: <http://jena.apache.org/2016/tdb#> .
> @prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> @prefix fuseki: <http://jena.apache.org/fuseki#> .
> 
> :theServiceBI a fuseki:Service ;
> rdfs:label "Service with update and query to test minimal dataset with custom built-in inference using an instance of generic rule reasoner" ;
> fuseki:dataset :theDatasetBI ;
> #:tdb_dataset_readwrite ;
> fuseki:name "ConferenceBuiltIn" ;
> fuseki:serviceQuery "query" , "sparql" ;
> fuseki:serviceReadGraphStore "get" ;
> fuseki:serviceReadWriteGraphStore
> "data" ;
> fuseki:serviceUpdate "update" ;
> fuseki:serviceUpload "upload" .
> 
> :theDatasetBI a ja:RDFDataset ;
> ja:defaultGraph <#theModel_GRRBI> .
> 
> <#theModel_GRRBI> a ja:InfModel ;
> ja:baseModel <#theGraphBI> ;
> ja:reasoner [
> ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
> ja:rulesFrom <file:///C:/dev/apache-jena-fuseki-3.10.0/data/conference/conference2.rules>
> ] ;
> .
> 
> <#theGraphBI> rdf:type tdb2:GraphTDB ;
> tdb2:dataset :theTDB2DatasetBI .
> 
> :theTDB2DatasetBI
> a tdb2:DatasetTDB2 ;
> tdb2:location "C:\\dev\\apache-jena-fuseki-3.10.0\\run/databases/ConferenceBuiltIn" ;
> tdb2:unionDefaultGraph true.
> 
> <END CONFIG FILE>
> 
> This is my query:
> -----------------------
> 
> prefix ns: <http://test.org#>
> select *
> where
> {?x ns:r ?z}
> limit 5
> 
> This is Fuskei's log:
> --------------------------
> 
> [2019-05-31 18:47:22] Server INFO Started 2019/05/31 18:47:22 BST on port 3030
> [2019-05-31 18:47:30] Fuseki INFO [1] POST http://localhost:3030/ConferenceBuiltIn/sparql
> [2019-05-31 18:47:30] Fuseki INFO [1] Query = prefix ns: <http://test.org#> select * where {?x ns:r ?z} limit 5
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor WARN Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Fuseki INFO [1] 200 OK (78 ms)
> 
> ###### END OF MESSAGE
> 
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
> 
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
> 
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
> 
> 
> From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
> Sent: 17 May 2019 09:01
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
> 
> Hi Pierre,
> 
> I can't offer to hold you by the hand I'm afraid, snowed under with
> work. But a minimal example might help. Here's an example of a minimal
> extension builtin:
> 
> class StringEqualIgnoreCase extends BaseBuiltin implements Builtin {
> 
> public String getName() {
> return "stringEqualIgnoreCase";
> }
> 
> @Override
> public int getArgLength() {
> return 2;
> }
> 
> @Override
> public boolean bodyCall(Node[] args, int length, RuleContext context) {
> checkArgs(length, context);
> Node n1 = getArg(0, args, context);
> Node n2 = getArg(1, args, context);
> if (n1.isLiteral() && n1.isLiteral()) {
> return n1.getLiteralLexicalForm().equalsIgnoreCase(
> n2.getLiteralLexicalForm() );
> } else {
> return false;
> }
> }
> 
> }
> 
> and an example driver class for demonstrating it operating:
> 
> /**
> * Rule test.
> */
> public void testRuleSet2() {
> String NS = "http://ont.com/";
> BuiltinRegistry.theRegistry.register( new
> StringEqualIgnoreCase() );
> String rules = "[r1: (?x ns:p ?pl) (?x ns:q ?ql)
> stringEqualIgnoreCase(?pl, ?ql) -> (?x ns:r 'equal') ]";
> Model m = ModelFactory.createDefaultModel();
> Resource a = m.createResource(NS + "a");
> Resource b = m.createResource(NS + "b");
> Property p = m.createProperty(NS + "p");
> Property q = m.createProperty(NS + "q");
> m.add(a, p, "FOO");
> m.add(a, q, "foo");
> m.add(b, p, "FOO");
> m.add(b, q, "foobar");
> GenericRuleReasoner reasoner = new GenericRuleReasoner(Rule
> .parseRules(rules));
> InfModel infModel = ModelFactory.createInfModel(reasoner, m);
> infModel.write(System.out, "Turtle");
> }
> 
> These are cut/paste from some very ancient examples but hopefully should
> work, if not let us know I can see about assembling it into a self
> contained working example.
> 
> As it says in the documentation, for examples of how to write particular
> sorts of builtin then the best place is to look is the source code for
> the current builtins.
> 
> Dave
> 
> On 17/05/2019 07:53, Pierre Grenon wrote:
>> Hi
>>
>> Thanks again.
>>
>> Hear you.
>>
>> I think this is becoming a bit too meta perhaps. Maybe there’s a couple of ways to go forward.
>>
>>
>> a. Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me.
>>
>> b. I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?
>>
>> Give a shout.
>>
>> Thanks,
>> Pierre
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 17 May 2019 07:24
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> Hi,
>>
>>> Hi Lorenz,
>>>
>>> Thank you for your answer.
>>>
>>> Quick follow up.
>>>
>>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
>> I can see that it might be too abstract for people coming from different
>> areas, sure. But, the question is who is able to provide such a tutorial
>> and also who has the time. It's always a trade-off in Open Source
>> projects like Jena - I guess most of the devs or other project related
>> people here are not getting payed, and clearly such a tutorial for most
>> if not all of the built-ins definitely needs some effort. Ideally, the
>> community could take over those things, but looks like nobody ever wrote
>> blog posts or tutorials about the Jena rule system and its built-ins.
>>>
>>>
>>>
>>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
>> I don't think you can use functions or expressions from the SPARQL
>> engine resp. its XPath constructors. Both are totally different
>> implementations I guess - but again, I'm not a developer, so I can't
>> make a valid statement, except for looking into the code and the docs.
>> From my point of view, only the mentioned built-ins from the docs are
>> valid so far.
>>>
>>>
>>>
>>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>>
>>> What’s wrong with :
>>>
>>>
>>>
>>> [ruleMissedDeadline2:
>>>
>>> (?conference ns:hasDeadline ?date)
>>>
>>> now(?now)
>>>
>>> greaterThan(?now, ?date)
>>>
>>> ->
>>>
>>> (?conference ns:status ns:DeadlinePassed)
>>>
>>> ]
>>
>> Well I was clearly thinking too complicated, so yes, your rule should
>> work given that the docs say
>>
>>> lessThan(?x, ?y), greaterThan(?x, ?y)
>>> le(?x, ?y), ge(?x, ?y)
>>>
>>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>>> or time instants (can be integer or floating point or XSDDateTime).
>> I was more thinking about things like inferring the age of a person
>> isn't possible right now, but would clearly be some nice to have feature
>> such that you could have it as implicit fact in your KB without the need
>> to change the asserted data every year.
>>
>>>
>>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
>>
>> That's also something I can't answer properly. I mean, yes, you can
>> create custom built-ins and register those or maybe create an overriding
>> registry [1] ? But not sure, it looks like at least the overriding
>> registry would have to be used by the rule parser, so I don't know how
>> you would have to combine it with Fuseki. And in the end, yes, you have
>> to repackage Fuseki I think as long as you modify the existing
>> BuiltinRegistry.
>>
>> Maybe there is also some other kind of plugin system here, but that can
>> only be answered by Andy, Dave, Adam, etc.
>>
>>
>> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>
>>
>>>
>>> Many thanks,
>>> Pierre
>>>
>>>
>>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>>> Sent: 16 May 2019 08:33
>>> To: users@jena.apache.org
>>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>>
>>> I'm not aware of any tutorial, but afaik you can't do what you did here
>>> with SPARQL in Jena rules without writing custom built-ins or by
>>> extending the existing ones because:
>>>
>>> * the "difference" built-in does only work for numbers right now [1]
>>>
>>> * there is no support for duration type at all it looks like
>>>
>>>
>>> So, so far you could only compare datetime values via lessThan, le,
>>> greaterThan, ge but there is no other built-in with support for date
>>> values so far. Others might indeed correct me if I'm wrong of.
>>>
>>>
>>> It looks like, you have to extend the rule system by custom built-ins -
>>> it's not that difficult though [2]
>>>
>>> [1]
>>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
>>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>>>
>>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>>
>>>> Example:
>>>>
>>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>>
>>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>>
>>>> SELECT * WHERE {
>>>> ?subject here:hasDeadline ?date .
>>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>>> FILTER(?Span < "P0D"^^xsd:duration)
>>>> }
>>>>
>>>> SELECT * WHERE {
>>>> ?subject here:hasDeadline ?date .
>>>> FILTER(now() > xsd:dateTime(?date))
>>>> }
>>>>
>>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>>
>>>> ?subject here:hasStatus here:DeadlinePassed
>>>>
>>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>>
>>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>>
>>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>>
>>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>>>
>>>>
>>>> With many thanks and kind regards,
>>>> Pierre
>>>>
>>> --
>>> Lorenz Bühmann
>>> AKSW group, University of Leipzig
>>> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>> - semantic web research center
>>>
>>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>>
>>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>)
>>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>.
>>>
>>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>>
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org<http://aksw.org> - semantic web research center
>>
>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>
>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
>>
>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>
>>

Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Dave Reynolds <da...@gmail.com>.
Hi Pierre,

I'm afraid I've lost track of what you are tying to do. Originally it 
seemed to be a problem running comparisons on date time values but 
Lorenz has already answered that.

In terms on writing your own new Builtins, then before you can use a new 
rule Builtin it needs to be registered. That's what the line:

BuiltinRegistry.theRegistry.register( new StringEqualIgnoreCase() )

was doing in my (non-fuseki) example.

If you need your new builtin to run within fuseki then you would need 
some way to trigger such registration code. No doubt that's possible but 
not something I've any first hand knowledge of.

By the way, for simply getting code loaded into fuseki you don't need to 
repack the jar. Just add your new jar to the classpath and use the 
ja:loadClass function to get your class loaded when fuseki starts up. 
See last example in:

https://jena.apache.org/documentation/fuseki2/fuseki-configuration.html

Dave

On 03/06/2019 07:01, Pierre Grenon wrote:
> Hi Dave,
> 
> Executive summary:
> 
> I'm not a java coder. I did what I could to try to do this using fuseki.
> 
> I get this:
> [2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
> 
> I understand this may be related to RuleContext. I don't understand any further.
> Details below.
> 
> With many thanks,
> Pierre
> 
> Details ---
> 
> 1. I unzipped my fuseki-server.jar
> 
> 2. I placed the code below into a ..\rulesys\testBuilt.java as
> 
> <BEGIN CODE>
> package org.apache.jena.reasoner.rulesys.builtins;
> 
> 
> import org.apache.jena.graph.* ;
> import org.apache.jena.reasoner.rulesys.* ;
> 
> /**
>   * Tests if the first argument is less than the second.
>   */
> 
> class testBuilt extends BaseBuiltin implements Builtin {
> 	public String getName() {
> 		return "testBuilt";
> 		}
> 		
> 		@Override
> 		public int getArgLength() {
> 			return 2;
> 			}
> 			
> 			@Override
> 			public boolean bodyCall(Node[] args, int length, RuleContext context) {
> 				checkArgs(length, context);
> 				Node n1 = getArg(0, args, context);
> 				Node n2 = getArg(1, args, context);
> 				if (n1.isLiteral() && n1.isLiteral()) {
> 					return n1.getLiteralLexicalForm().equalsIgnoreCase(
> 					n2.getLiteralLexicalForm() );
> 					} else {
> 						return false;
> 						}
> 						}
> 						}
> 
> <END CODE>				
> 
> 3. Compiled that:
> 
> C:\dev\apache-jena-fuseki-3.10.0\woot>javac org\apache\jena\reasoner\rulesys\builtins\testBuilt.java
> 
> 4. Jar-ed the whole thing back
> 
> C:\dev\apache-jena-fuseki-3.10.0\woot>jar cmvf fuseki-server\META-INF\MANIFEST.MF fuseki-server.jar -C fuseki-server/ .
> 
> 5. Replaced my fuseki-server.jar
> 
> 6. Created a rule file
> 
> <BEGIN RULE FILE>
> @prefix ns: <http://test.org#> .
> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> 
> [r1:
> (?x ns:p ?pl)
> (?x ns:q ?ql)
> testBuilt(?pl, ?ql)
> ->
> (?x ns:r 'equal')
> ]
> <END RULE FILE>
> 
> 7. Created a dataset file
> 
> <BEGIN DATASET FILE>
> @prefix ns: <http://test.org#> .
> @prefix owl: <http://www.w3.org/2002/07/owl#> .
> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix xml: <http://www.w3.org/XML/1998/namespace> .
> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> 
> <http://test.org#Conference0> ns:p "PenguiN" .
> <http://test.org#Conference0> ns:q "penguin" .
> <http://test.org#Conference1> ns:p "penguin" .
> <http://test.org#Conference1> ns:q "penGuin" .
> <http://test.org#Conference2> ns:p "Penguin" .
> <http://test.org#Conference2> ns:q "penguin" .
> <http://test.org#Workshop1> ns:p "Noot" .
> <http://test.org#Workshop1> ns:q "noot" .
> <http://test.org#Workshop2> ns:p "NootNoot" .
> <http://test.org#Workshop2> ns:q "nootNoot" .
> 	
> <END DATASET FILE>
> 
> 
> 8. Created a config file on the previous model to use the above
> 
> <BEGIN CONFIG FILE>
> @prefix :      <http://base/#> .
> @prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix tdb2:  <http://jena.apache.org/2016/tdb#> .
> @prefix ja:    <http://jena.hpl.hp.com/2005/11/Assembler#> .
> @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
> @prefix fuseki: <http://jena.apache.org/fuseki#> .
> 
> :theServiceBI a                   fuseki:Service ;
>          rdfs:label                    "Service with update and query to test minimal dataset with custom built-in inference using an instance of generic rule reasoner" ;
>          fuseki:dataset                :theDatasetBI ;
> 		#:tdb_dataset_readwrite ;
>          fuseki:name                   "ConferenceBuiltIn" ;
>          fuseki:serviceQuery           "query" , "sparql" ;
>          fuseki:serviceReadGraphStore  "get" ;
>          fuseki:serviceReadWriteGraphStore
>                  "data" ;
>          fuseki:serviceUpdate          "update" ;
>          fuseki:serviceUpload          "upload" .
> 
> :theDatasetBI a ja:RDFDataset ;
>      ja:defaultGraph <#theModel_GRRBI> .
> 		
> <#theModel_GRRBI> a ja:InfModel ;
>      ja:baseModel <#theGraphBI> ;
> 	ja:reasoner [
> 		ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
> 		ja:rulesFrom <file:///C:/dev/apache-jena-fuseki-3.10.0/data/conference/conference2.rules>
> 	] ;
> .
> 		
> <#theGraphBI> rdf:type tdb2:GraphTDB ;
>     tdb2:dataset :theTDB2DatasetBI .
> 		
> :theTDB2DatasetBI
>          a              tdb2:DatasetTDB2 ;
>          tdb2:location  "C:\\dev\\apache-jena-fuseki-3.10.0\\run/databases/ConferenceBuiltIn" ;
> 		tdb2:unionDefaultGraph true.
> 
> <END CONFIG FILE>
> 
> This is my query:
> -----------------------
> 
> prefix ns: <http://test.org#>
> select *
> where
> {?x ns:r ?z}
> limit 5
> 
> This is Fuskei's log:
> --------------------------
> 
> [2019-05-31 18:47:22] Server     INFO  Started 2019/05/31 18:47:22 BST on port 3030
> [2019-05-31 18:47:30] Fuseki     INFO  [1] POST http://localhost:3030/ConferenceBuiltIn/sparql
> [2019-05-31 18:47:30] Fuseki     INFO  [1] Query = prefix ns: <http://test.org#> select * where  {?x ns:r ?z} limit 5
> [2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
> [2019-05-31 18:47:30] Fuseki     INFO  [1] 200 OK (78 ms)
> 
> ###### END OF MESSAGE
> 
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
> 
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
> 
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
> 
> 
> From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
> Sent: 17 May 2019 09:01
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
> 
> Hi Pierre,
> 
> I can't offer to hold you by the hand I'm afraid, snowed under with
> work. But a minimal example might help. Here's an example of a minimal
> extension builtin:
> 
> class StringEqualIgnoreCase extends BaseBuiltin implements Builtin {
> 
> public String getName() {
> return "stringEqualIgnoreCase";
> }
> 
> @Override
> public int getArgLength() {
> return 2;
> }
> 
> @Override
> public boolean bodyCall(Node[] args, int length, RuleContext context) {
> checkArgs(length, context);
> Node n1 = getArg(0, args, context);
> Node n2 = getArg(1, args, context);
> if (n1.isLiteral() && n1.isLiteral()) {
> return n1.getLiteralLexicalForm().equalsIgnoreCase(
> n2.getLiteralLexicalForm() );
> } else {
> return false;
> }
> }
> 
> }
> 
> and an example driver class for demonstrating it operating:
> 
> /**
> * Rule test.
> */
> public void testRuleSet2() {
> String NS = "http://ont.com/";
> BuiltinRegistry.theRegistry.register( new
> StringEqualIgnoreCase() );
> String rules = "[r1: (?x ns:p ?pl) (?x ns:q ?ql)
> stringEqualIgnoreCase(?pl, ?ql) -> (?x ns:r 'equal') ]";
> Model m = ModelFactory.createDefaultModel();
> Resource a = m.createResource(NS + "a");
> Resource b = m.createResource(NS + "b");
> Property p = m.createProperty(NS + "p");
> Property q = m.createProperty(NS + "q");
> m.add(a, p, "FOO");
> m.add(a, q, "foo");
> m.add(b, p, "FOO");
> m.add(b, q, "foobar");
> GenericRuleReasoner reasoner = new GenericRuleReasoner(Rule
> .parseRules(rules));
> InfModel infModel = ModelFactory.createInfModel(reasoner, m);
> infModel.write(System.out, "Turtle");
> }
> 
> These are cut/paste from some very ancient examples but hopefully should
> work, if not let us know I can see about assembling it into a self
> contained working example.
> 
> As it says in the documentation, for examples of how to write particular
> sorts of builtin then the best place is to look is the source code for
> the current builtins.
> 
> Dave
> 
> On 17/05/2019 07:53, Pierre Grenon wrote:
>> Hi
>>
>> Thanks again.
>>
>> Hear you.
>>
>> I think this is becoming a bit too meta perhaps. Maybe there’s a couple of ways to go forward.
>>
>>
>> a. Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me.
>>
>> b. I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?
>>
>> Give a shout.
>>
>> Thanks,
>> Pierre
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 17 May 2019 07:24
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> Hi,
>>
>>> Hi Lorenz,
>>>
>>> Thank you for your answer.
>>>
>>> Quick follow up.
>>>
>>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
>> I can see that it might be too abstract for people coming from different
>> areas, sure. But, the question is who is able to provide such a tutorial
>> and also who has the time. It's always a trade-off in Open Source
>> projects like Jena - I guess most of the devs or other project related
>> people here are not getting payed, and clearly such a tutorial for most
>> if not all of the built-ins definitely needs some effort. Ideally, the
>> community could take over those things, but looks like nobody ever wrote
>> blog posts or tutorials about the Jena rule system and its built-ins.
>>>
>>>
>>>
>>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
>> I don't think you can use functions or expressions from the SPARQL
>> engine resp. its XPath constructors. Both are totally different
>> implementations I guess - but again, I'm not a developer, so I can't
>> make a valid statement, except for looking into the code and the docs.
>>  From my point of view, only the mentioned built-ins from the docs are
>> valid so far.
>>>
>>>
>>>
>>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>>
>>> What’s wrong with :
>>>
>>>
>>>
>>> [ruleMissedDeadline2:
>>>
>>> (?conference ns:hasDeadline ?date)
>>>
>>> now(?now)
>>>
>>> greaterThan(?now, ?date)
>>>
>>> ->
>>>
>>> (?conference ns:status ns:DeadlinePassed)
>>>
>>> ]
>>
>> Well I was clearly thinking too complicated, so yes, your rule should
>> work given that the docs say
>>
>>> lessThan(?x, ?y), greaterThan(?x, ?y)
>>> le(?x, ?y), ge(?x, ?y)
>>>
>>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>>> or time instants (can be integer or floating point or XSDDateTime).
>> I was more thinking about things like inferring the age of a person
>> isn't possible right now, but would clearly be some nice to have feature
>> such that you could have it as implicit fact in your KB without the need
>> to change the asserted data every year.
>>
>>>
>>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
>>
>> That's also something I can't answer properly. I mean, yes, you can
>> create custom built-ins and register those or maybe create an overriding
>> registry [1] ? But not sure, it looks like at least the overriding
>> registry would have to be used by the rule parser, so I don't know how
>> you would have to combine it with Fuseki. And in the end, yes, you have
>> to repackage Fuseki I think as long as you modify the existing
>> BuiltinRegistry.
>>
>> Maybe there is also some other kind of plugin system here, but that can
>> only be answered by Andy, Dave, Adam, etc.
>>
>>
>> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>
>>
>>>
>>> Many thanks,
>>> Pierre
>>>
>>>
>>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>>> Sent: 16 May 2019 08:33
>>> To: users@jena.apache.org
>>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>>
>>> I'm not aware of any tutorial, but afaik you can't do what you did here
>>> with SPARQL in Jena rules without writing custom built-ins or by
>>> extending the existing ones because:
>>>
>>> * the "difference" built-in does only work for numbers right now [1]
>>>
>>> * there is no support for duration type at all it looks like
>>>
>>>
>>> So, so far you could only compare datetime values via lessThan, le,
>>> greaterThan, ge but there is no other built-in with support for date
>>> values so far. Others might indeed correct me if I'm wrong of.
>>>
>>>
>>> It looks like, you have to extend the rule system by custom built-ins -
>>> it's not that difficult though [2]
>>>
>>> [1]
>>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
>>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>>>
>>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>>
>>>> Example:
>>>>
>>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>>
>>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>>
>>>> SELECT * WHERE {
>>>> ?subject here:hasDeadline ?date .
>>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>>> FILTER(?Span < "P0D"^^xsd:duration)
>>>> }
>>>>
>>>> SELECT * WHERE {
>>>> ?subject here:hasDeadline ?date .
>>>> FILTER(now() > xsd:dateTime(?date))
>>>> }
>>>>
>>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>>
>>>> ?subject here:hasStatus here:DeadlinePassed
>>>>
>>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>>
>>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>>
>>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>>
>>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>>>
>>>>
>>>> With many thanks and kind regards,
>>>> Pierre
>>>>
>>> --
>>> Lorenz Bühmann
>>> AKSW group, University of Leipzig
>>> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>> - semantic web research center
>>>
>>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>>
>>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>)
>>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>.
>>>
>>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>>
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org<http://aksw.org> - semantic web research center
>>
>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>
>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
>>
>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>
>>

RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
Hi Dave, 

Executive summary: 

I'm not a java coder. I did what I could to try to do this using fuseki. 

I get this: 
[2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1

I understand this may be related to RuleContext. I don't understand any further.
Details below. 

With many thanks, 
Pierre

Details --- 

1. I unzipped my fuseki-server.jar 

2. I placed the code below into a ..\rulesys\testBuilt.java as 

<BEGIN CODE>
package org.apache.jena.reasoner.rulesys.builtins;


import org.apache.jena.graph.* ;
import org.apache.jena.reasoner.rulesys.* ;

/**
 * Tests if the first argument is less than the second.
 */

class testBuilt extends BaseBuiltin implements Builtin {
	public String getName() {
		return "testBuilt";
		}
		
		@Override
		public int getArgLength() {
			return 2;
			}
			
			@Override
			public boolean bodyCall(Node[] args, int length, RuleContext context) {
				checkArgs(length, context);
				Node n1 = getArg(0, args, context);
				Node n2 = getArg(1, args, context);
				if (n1.isLiteral() && n1.isLiteral()) {
					return n1.getLiteralLexicalForm().equalsIgnoreCase( 
					n2.getLiteralLexicalForm() );
					} else {
						return false;
						}
						}
						}

<END CODE>				

3. Compiled that:

C:\dev\apache-jena-fuseki-3.10.0\woot>javac org\apache\jena\reasoner\rulesys\builtins\testBuilt.java

4. Jar-ed the whole thing back

C:\dev\apache-jena-fuseki-3.10.0\woot>jar cmvf fuseki-server\META-INF\MANIFEST.MF fuseki-server.jar -C fuseki-server/ .

5. Replaced my fuseki-server.jar

6. Created a rule file 

<BEGIN RULE FILE> 
@prefix ns: <http://test.org#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

[r1: 
(?x ns:p ?pl) 
(?x ns:q ?ql)
testBuilt(?pl, ?ql) 
-> 
(?x ns:r 'equal') 
]
<END RULE FILE>

7. Created a dataset file 

<BEGIN DATASET FILE>
@prefix ns: <http://test.org#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<http://test.org#Conference0> ns:p "PenguiN" .
<http://test.org#Conference0> ns:q "penguin" .
<http://test.org#Conference1> ns:p "penguin" .
<http://test.org#Conference1> ns:q "penGuin" .
<http://test.org#Conference2> ns:p "Penguin" .
<http://test.org#Conference2> ns:q "penguin" .
<http://test.org#Workshop1> ns:p "Noot" .
<http://test.org#Workshop1> ns:q "noot" .
<http://test.org#Workshop2> ns:p "NootNoot" .
<http://test.org#Workshop2> ns:q "nootNoot" .
	
<END DATASET FILE>


8. Created a config file on the previous model to use the above

<BEGIN CONFIG FILE>
@prefix :      <http://base/#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix tdb2:  <http://jena.apache.org/2016/tdb#> .
@prefix ja:    <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .

:theServiceBI a                   fuseki:Service ;
        rdfs:label                    "Service with update and query to test minimal dataset with custom built-in inference using an instance of generic rule reasoner" ;
        fuseki:dataset                :theDatasetBI ;
		#:tdb_dataset_readwrite ;
        fuseki:name                   "ConferenceBuiltIn" ;
        fuseki:serviceQuery           "query" , "sparql" ;
        fuseki:serviceReadGraphStore  "get" ;
        fuseki:serviceReadWriteGraphStore
                "data" ;
        fuseki:serviceUpdate          "update" ;
        fuseki:serviceUpload          "upload" .

:theDatasetBI a ja:RDFDataset ; 
    ja:defaultGraph <#theModel_GRRBI> .
		
<#theModel_GRRBI> a ja:InfModel ;
    ja:baseModel <#theGraphBI> ;
	ja:reasoner [
		ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
		ja:rulesFrom <file:///C:/dev/apache-jena-fuseki-3.10.0/data/conference/conference2.rules> 
	] ;
.
		
<#theGraphBI> rdf:type tdb2:GraphTDB ;
   tdb2:dataset :theTDB2DatasetBI .
		
:theTDB2DatasetBI
        a              tdb2:DatasetTDB2 ;
        tdb2:location  "C:\\dev\\apache-jena-fuseki-3.10.0\\run/databases/ConferenceBuiltIn" ;
		tdb2:unionDefaultGraph true.

<END CONFIG FILE>

This is my query: 
-----------------------

prefix ns: <http://test.org#>
select *
where 
{?x ns:r ?z}
limit 5

This is Fuskei's log: 
--------------------------

[2019-05-31 18:47:22] Server     INFO  Started 2019/05/31 18:47:22 BST on port 3030
[2019-05-31 18:47:30] Fuseki     INFO  [1] POST http://localhost:3030/ConferenceBuiltIn/sparql
[2019-05-31 18:47:30] Fuseki     INFO  [1] Query = prefix ns: <http://test.org#> select * where  {?x ns:r ?z} limit 5
[2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
[2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
[2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
[2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
[2019-05-31 18:47:30] Functor    WARN  Invoking undefined functor testBuilt in r1
[2019-05-31 18:47:30] Fuseki     INFO  [1] 200 OK (78 ms)

###### END OF MESSAGE

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.


From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com] 
Sent: 17 May 2019 09:01
To: users@jena.apache.org
Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Hi Pierre,

I can't offer to hold you by the hand I'm afraid, snowed under with 
work. But a minimal example might help. Here's an example of a minimal 
extension builtin:

class StringEqualIgnoreCase extends BaseBuiltin implements Builtin {

public String getName() {
return "stringEqualIgnoreCase";
}

@Override
public int getArgLength() {
return 2;
}

@Override
public boolean bodyCall(Node[] args, int length, RuleContext context) {
checkArgs(length, context);
Node n1 = getArg(0, args, context);
Node n2 = getArg(1, args, context);
if (n1.isLiteral() && n1.isLiteral()) {
return n1.getLiteralLexicalForm().equalsIgnoreCase( 
n2.getLiteralLexicalForm() );
} else {
return false;
}
}

}

and an example driver class for demonstrating it operating:

/**
* Rule test.
*/
public void testRuleSet2() {
String NS = "http://ont.com/";
BuiltinRegistry.theRegistry.register( new 
StringEqualIgnoreCase() );
String rules = "[r1: (?x ns:p ?pl) (?x ns:q ?ql) 
stringEqualIgnoreCase(?pl, ?ql) -> (?x ns:r 'equal') ]";
Model m = ModelFactory.createDefaultModel();
Resource a = m.createResource(NS + "a");
Resource b = m.createResource(NS + "b");
Property p = m.createProperty(NS + "p");
Property q = m.createProperty(NS + "q");
m.add(a, p, "FOO");
m.add(a, q, "foo");
m.add(b, p, "FOO");
m.add(b, q, "foobar");
GenericRuleReasoner reasoner = new GenericRuleReasoner(Rule
.parseRules(rules));
InfModel infModel = ModelFactory.createInfModel(reasoner, m);
infModel.write(System.out, "Turtle");
}

These are cut/paste from some very ancient examples but hopefully should 
work, if not let us know I can see about assembling it into a self 
contained working example.

As it says in the documentation, for examples of how to write particular 
sorts of builtin then the best place is to look is the source code for 
the current builtins.

Dave

On 17/05/2019 07:53, Pierre Grenon wrote:
> Hi
> 
> Thanks again.
> 
> Hear you.
> 
> I think this is becoming a bit too meta perhaps. Maybe there’s a couple of ways to go forward.
> 
> 
> a. Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me.
> 
> b. I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?
> 
> Give a shout.
> 
> Thanks,
> Pierre
> 
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 17 May 2019 07:24
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
> 
> Hi,
> 
>> Hi Lorenz,
>>
>> Thank you for your answer.
>>
>> Quick follow up.
>>
>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
> I can see that it might be too abstract for people coming from different
> areas, sure. But, the question is who is able to provide such a tutorial
> and also who has the time. It's always a trade-off in Open Source
> projects like Jena - I guess most of the devs or other project related
> people here are not getting payed, and clearly such a tutorial for most
> if not all of the built-ins definitely needs some effort. Ideally, the
> community could take over those things, but looks like nobody ever wrote
> blog posts or tutorials about the Jena rule system and its built-ins.
>>
>>
>>
>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
> I don't think you can use functions or expressions from the SPARQL
> engine resp. its XPath constructors. Both are totally different
> implementations I guess - but again, I'm not a developer, so I can't
> make a valid statement, except for looking into the code and the docs.
> From my point of view, only the mentioned built-ins from the docs are
> valid so far.
>>
>>
>>
>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>
>> What’s wrong with :
>>
>>
>>
>> [ruleMissedDeadline2:
>>
>> (?conference ns:hasDeadline ?date)
>>
>> now(?now)
>>
>> greaterThan(?now, ?date)
>>
>> ->
>>
>> (?conference ns:status ns:DeadlinePassed)
>>
>> ]
> 
> Well I was clearly thinking too complicated, so yes, your rule should
> work given that the docs say
> 
>> lessThan(?x, ?y), greaterThan(?x, ?y)
>> le(?x, ?y), ge(?x, ?y)
>>
>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>> or time instants (can be integer or floating point or XSDDateTime).
> I was more thinking about things like inferring the age of a person
> isn't possible right now, but would clearly be some nice to have feature
> such that you could have it as implicit fact in your KB without the need
> to change the asserted data every year.
> 
>>
>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
> 
> That's also something I can't answer properly. I mean, yes, you can
> create custom built-ins and register those or maybe create an overriding
> registry [1] ? But not sure, it looks like at least the overriding
> registry would have to be used by the rule parser, so I don't know how
> you would have to combine it with Fuseki. And in the end, yes, you have
> to repackage Fuseki I think as long as you modify the existing
> BuiltinRegistry.
> 
> Maybe there is also some other kind of plugin system here, but that can
> only be answered by Andy, Dave, Adam, etc.
> 
> 
> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>
> 
>>
>> Many thanks,
>> Pierre
>>
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 16 May 2019 08:33
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> I'm not aware of any tutorial, but afaik you can't do what you did here
>> with SPARQL in Jena rules without writing custom built-ins or by
>> extending the existing ones because:
>>
>> * the "difference" built-in does only work for numbers right now [1]
>>
>> * there is no support for duration type at all it looks like
>>
>>
>> So, so far you could only compare datetime values via lessThan, le,
>> greaterThan, ge but there is no other built-in with support for date
>> values so far. Others might indeed correct me if I'm wrong of.
>>
>>
>> It looks like, you have to extend the rule system by custom built-ins -
>> it's not that difficult though [2]
>>
>> [1]
>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>>
>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>
>>> Example:
>>>
>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>
>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>> FILTER(?Span < "P0D"^^xsd:duration)
>>> }
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> FILTER(now() > xsd:dateTime(?date))
>>> }
>>>
>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>
>>> ?subject here:hasStatus here:DeadlinePassed
>>>
>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>
>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>
>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>
>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>>
>>>
>>> With many thanks and kind regards,
>>> Pierre
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>> - semantic web research center
>>
>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>
>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>)
>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>.
>>
>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org<http://aksw.org> - semantic web research center
> 
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
> 
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
> 
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
> 
> 

Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Dave Reynolds <da...@gmail.com>.
Hi Pierre,

I can't offer to hold you by the hand I'm afraid, snowed under with 
work. But a minimal example might help. Here's an example of a minimal 
extension builtin:

class StringEqualIgnoreCase extends BaseBuiltin implements Builtin {

     public String getName() {
         return "stringEqualIgnoreCase";
     }

     @Override
     public int getArgLength() {
         return 2;
     }

     @Override
     public boolean bodyCall(Node[] args, int length, RuleContext context) {
         checkArgs(length, context);
         Node n1 = getArg(0, args, context);
         Node n2 = getArg(1, args, context);
         if (n1.isLiteral() && n1.isLiteral()) {
             return n1.getLiteralLexicalForm().equalsIgnoreCase( 
n2.getLiteralLexicalForm() );
         } else {
             return false;
         }
     }

}

and an example driver class for demonstrating it operating:

     /**
      * Rule test.
      */
     public void testRuleSet2() {
         String NS = "http://ont.com/";
         BuiltinRegistry.theRegistry.register( new 
StringEqualIgnoreCase() );
         String rules = "[r1: (?x ns:p ?pl) (?x ns:q ?ql) 
stringEqualIgnoreCase(?pl, ?ql) -> (?x ns:r 'equal') ]";
         Model m = ModelFactory.createDefaultModel();
         Resource a = m.createResource(NS + "a");
         Resource b = m.createResource(NS + "b");
         Property p = m.createProperty(NS + "p");
         Property q = m.createProperty(NS + "q");
         m.add(a, p, "FOO");
         m.add(a, q, "foo");
         m.add(b, p, "FOO");
         m.add(b, q, "foobar");
         GenericRuleReasoner reasoner = new GenericRuleReasoner(Rule
                 .parseRules(rules));
         InfModel infModel = ModelFactory.createInfModel(reasoner, m);
         infModel.write(System.out, "Turtle");
     }

These are cut/paste from some very ancient examples but hopefully should 
work, if not let us know I can see about assembling it into a self 
contained working example.

As it says in the documentation, for examples of how to write particular 
sorts of builtin then the best place is to look is the source code for 
the current builtins.

Dave

On 17/05/2019 07:53, Pierre Grenon wrote:
> Hi
> 
> Thanks again.
> 
> Hear you.
> 
> I think this is becoming a bit too meta perhaps. Maybe there’s a couple of ways to go forward.
> 
> 
> a.      Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me.
> 
> b.      I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?
> 
> Give a shout.
> 
> Thanks,
> Pierre
> 
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 17 May 2019 07:24
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
> 
> Hi,
> 
>> Hi Lorenz,
>>
>> Thank you for your answer.
>>
>> Quick follow up.
>>
>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
> I can see that it might be too abstract for people coming from different
> areas, sure. But, the question is who is able to provide such a tutorial
> and also who has the time. It's always a trade-off in Open Source
> projects like Jena - I guess most of the devs or other project related
> people here are not getting payed, and clearly such a tutorial for most
> if not all of the built-ins definitely needs some effort. Ideally, the
> community could take over those things, but looks like nobody ever wrote
> blog posts or tutorials about the Jena rule system and its built-ins.
>>
>>
>>
>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
> I don't think you can use functions or expressions from the SPARQL
> engine resp. its XPath constructors. Both are totally different
> implementations I guess - but again, I'm not a developer, so I can't
> make a valid statement, except for looking into the code and the docs.
>  From my point of view, only the mentioned built-ins from the docs are
> valid so far.
>>
>>
>>
>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>
>> What’s wrong with :
>>
>>
>>
>> [ruleMissedDeadline2:
>>
>> (?conference ns:hasDeadline ?date)
>>
>> now(?now)
>>
>> greaterThan(?now, ?date)
>>
>> ->
>>
>> (?conference ns:status ns:DeadlinePassed)
>>
>> ]
> 
> Well I was clearly thinking too complicated, so yes, your rule should
> work given that the docs say
> 
>> lessThan(?x, ?y), greaterThan(?x, ?y)
>> le(?x, ?y), ge(?x, ?y)
>>
>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>> or time instants (can be integer or floating point or XSDDateTime).
> I was more thinking about things like inferring the age of a person
> isn't possible right now, but would clearly be some nice to have feature
> such that you could have it as implicit fact in your KB without the need
> to change the asserted data every year.
> 
>>
>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
> 
> That's also something I can't answer properly. I mean, yes, you can
> create custom built-ins and register those or maybe create an overriding
> registry [1] ? But not sure, it looks like at least the overriding
> registry would have to be used by the rule parser, so I don't know how
> you would have to combine it with Fuseki. And in the end, yes, you have
> to repackage Fuseki I think as long as you modify the existing
> BuiltinRegistry.
> 
> Maybe there is also some other kind of plugin system here, but that can
> only be answered by Andy, Dave, Adam, etc.
> 
> 
> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>
> 
>>
>> Many thanks,
>> Pierre
>>
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 16 May 2019 08:33
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> I'm not aware of any tutorial, but afaik you can't do what you did here
>> with SPARQL in Jena rules without writing custom built-ins or by
>> extending the existing ones because:
>>
>> * the "difference" built-in does only work for numbers right now [1]
>>
>> * there is no support for duration type at all it looks like
>>
>>
>> So, so far you could only compare datetime values via lessThan, le,
>> greaterThan, ge but there is no other built-in with support for date
>> values so far. Others might indeed correct me if I'm wrong of.
>>
>>
>> It looks like, you have to extend the rule system by custom built-ins -
>> it's not that difficult though [2]
>>
>> [1]
>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>>
>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>
>>> Example:
>>>
>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>
>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>> FILTER(?Span < "P0D"^^xsd:duration)
>>> }
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> FILTER(now() > xsd:dateTime(?date))
>>> }
>>>
>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>
>>> ?subject here:hasStatus here:DeadlinePassed
>>>
>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>
>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>
>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>
>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>>
>>>
>>> With many thanks and kind regards,
>>> Pierre
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>> - semantic web research center
>>
>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>
>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>)
>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>.
>>
>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org<http://aksw.org> - semantic web research center
> 
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
> 
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/.
> 
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
> 
> 

RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
Further to the below. 

I am now pasting a config file in which I use both the Generic Rule Reasoner for the rule and RDFS for class subsumption.

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.


CAVEAT: This may appear trivial yet it was not straightforward to me how this works so any comment on this type of config is obviously most welcome independently of the dates aspect. 

On my end this concludes this part of the thread. I will use this config and the data as an extensible basis to figure out new built ins, although I have no clue when that might be -- all current conferences might have their deadlines passed by the time I get to this...

With many thanks and kind regards, 
Pierre 

For reference: 

/Conference1 allows deriving the expected facts from the rules but did not support RDFS 
/Conference2 allows returning bindings for the following query:
select * where 
{?x a <http://test.org#OrganisedEvent> . ?x <http://test.org#hasStatus> ?e} 


### START CONFIG 2: Conference_GRR_RDFS.ttl ###

@prefix :      <http://base/#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix tdb2:  <http://jena.apache.org/2016/tdb#> .
@prefix ja:    <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .

:theService a                   fuseki:Service ;
        rdfs:label                    "Service with update and query to test minimal dataset with inference using an instance of generic rule reasoner and RDFSExptRuleReasoner" ;
        fuseki:dataset                :theDataset ;
		#:tdb_dataset_readwrite ;
        fuseki:name                   "Conference2" ;
        fuseki:serviceQuery           "query" , "sparql" ;
        fuseki:serviceReadGraphStore  "get" ;
        fuseki:serviceReadWriteGraphStore
                "data" ;
        fuseki:serviceUpdate          "update" ;
        fuseki:serviceUpload          "upload" .

:theDataset a ja:RDFDataset ; 
    ja:defaultGraph <#theUnionModel>
	.

<#theUnionModel> a ja:UnionModel ;
		ja:rootModel <#theRootModel> ;
		ja:subModel <#theModel_GRR> , <#theModel_RDFS> .

<#theRootModel> a ja:Model ;
    ja:baseModel <#theGraph> ;
.

		
<#theModel_GRR> a ja:InfModel ;
    ja:baseModel <#theGraph> ;
	ja:reasoner [
		ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
		ja:rulesFrom <file:///C:/dev/apache-jena-fuseki-3.10.0/data/conference/conference1.rules> 
	] ;
.

<#theModel_RDFS> a ja:InfModel ;
    ja:baseModel <#theGraph> ;
	ja:reasoner [
	    ja:reasonerURL <http://jena.hpl.hp.com/2003/RDFSExptRuleReasoner> 
		] ;
.

<#theGraph> rdf:type tdb2:GraphTDB ;
   tdb2:dataset :theTDB2Dataset .
		
:theTDB2Dataset
        a              tdb2:DatasetTDB2 ;
        tdb2:location  "C:\\dev\\apache-jena-fuseki-3.10.0\\run/databases/Conference1" ;
		tdb2:unionDefaultGraph true.

### END CONFIG 2: Conference_GRR_RDFS.ttl ###		


> -----Original Message-----
> From: Pierre Grenon
> Sent: 23 May 2019 06:23
> To: 'users@jena.apache.org'
> Subject: RE: Documentation/tutorial on using dates in Jena rules with
> GenericRuleReasoner
> 
> Apologies for repost -- it *feels* like attaching stuff to emails is not the right
> thing to do. So, for all it's worth, as I would find it useful myself, files copied
> below.
> 
> Many thanks,
> Pierre
> 
> 
> 
> - Conference_GRR_onerule.ttl --- fuseki config with TDB2 and generic rule
> reasoner
> ### START CONFIG ###
> 
> @prefix :      <http://base/#> .
> @prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix tdb2:  <http://jena.apache.org/2016/tdb#> .
> @prefix ja:    <http://jena.hpl.hp.com/2005/11/Assembler#> .
> @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
> @prefix fuseki: <http://jena.apache.org/fuseki#> .
> 
> :theService a                   fuseki:Service ;
>         rdfs:label                    "Service with update and query to test minimal
> dataset with inference using an instance of generic rule reasoner" ;
>         fuseki:dataset                :theDataset ;
> 		#:tdb_dataset_readwrite ;
>         fuseki:name                   "Conference1" ;
>         fuseki:serviceQuery           "query" , "sparql" ;
>         fuseki:serviceReadGraphStore  "get" ;
>         fuseki:serviceReadWriteGraphStore
>                 "data" ;
>         fuseki:serviceUpdate          "update" ;
>         fuseki:serviceUpload          "upload" .
> 
> :theDataset a ja:RDFDataset ;
>     ja:defaultGraph <#theModel_GRR> .
> 
> <#theModel_GRR> a ja:InfModel ;
>     ja:baseModel <#theGraph> ;
> 	ja:reasoner [
> 		ja:reasonerURL
> <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
> 		ja:rulesFrom <file:///C:/dev/apache-jena-fuseki-
> 3.10.0/data/conference/conference1.rules>
> 	] ;
> .
> 
> <#theGraph> rdf:type tdb2:GraphTDB ;
>    tdb2:dataset :theTDB2Dataset .
> 
> :theTDB2Dataset
>         a              tdb2:DatasetTDB2 ;
>         tdb2:location  "C:\\dev\\apache-jena-fuseki-
> 3.10.0\\run/databases/Conference1" ;
> 		tdb2:unionDefaultGraph true.
> 
> ### END CONFIG ###
> 
> - conference1.ttl
> ### START DATA ###
> 
> @prefix : <http://test.org#> .
> @prefix owl: <http://www.w3.org/2002/07/owl#> .
> @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
> @prefix xml: <http://www.w3.org/XML/1998/namespace> .
> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> 
> ### OE
> <http://test.org#OrganisedEvent> rdf:type owl:Class ;
> 	rdfs:label "organised event" .
> 
> <http://test.org#Conference> rdf:type owl:Class ;
> 	rdfs:subClassOf <http://test.org#OrganisedEvent> ;
> 	rdfs:label "conference" .
> 
> <http://test.org#Workshop> rdf:type owl:Class ;
> 	rdfs:subClassOf <http://test.org#OrganisedEvent> ;
> 	rdfs:label "workshop" .
> 
> <http://test.org#hasDeadline> rdf:type owl:DatatypeProperty ;
> 	rdfs:domain <http://test.org#OrganisedEvent> ;
> 	rdfs:range xsd:dateTime ;
> 	rdfs:label "deadline passed" .
> 
> <http://test.org#Status> rdf:type owl:Class ;
> 	rdfs:label "Status" .
> 
> <http://test.org#hasStatus>
> 	rdf:type owl:ObjectProperty ;
> 	rdfs:domain <http://test.org#OrganisedEvent> ;
> 	rdfs:range <http://test.org#Status> ;
> 	rdfs:label "has status" .
> 
> <http://test.org#Status_DeadlinePassed>
> 	rdf:type owl:NamedIndividual , <http://test.org#Status> ;
> 	rdfs:label "deadline passed" .
> 
> <http://test.org#Status_DeadlineActive>
> 	rdf:type owl:NamedIndividual , <http://test.org#Status> ;
> 	rdfs:label "deadline active" .
> 
> 
> ### KB
> <http://test.org#Conference1> rdf:type owl:NamedIndividual ,
> <http://test.org#Conference> ;
> 	<http://test.org#hasDeadline>"2019-01-
> 01T00:00:00Z"^^xsd:dateTime ;
> 	rdfs:label "1st Intl Conf of the Penguin Appreciation Society" .
> 
> <http://test.org#Conference2> rdf:type owl:NamedIndividual ,
> <http://test.org#Conference> ;
> 	<http://test.org#hasDeadline>"3019-01-
> 01T00:00:00Z"^^xsd:dateTime ;
> 	rdfs:label "101st Conf of the Penguin Appreciation Society" .
> 
> <http://test.org#Workshop1> rdf:type owl:NamedIndividual ,
> <http://test.org#Workshop> ;
> 	<http://test.org#hasDeadline>"2018-07-
> 01T00:00:00Z"^^xsd:dateTime ;
> 	rdfs:label "How to walk like a penguin" .
> 
> <http://test.org#Workshop2> rdf:type owl:NamedIndividual ,
> <http://test.org#Workshop> ;
> 	<http://test.org#hasDeadline>"2030-07-
> 01T00:00:00Z"^^xsd:dateTime ;
> 	rdfs:label "Do penguins walk?" .
> 
> ### END DATA ###
> 
> - conference1.rules
> ### START RULE###
> @prefix ns: <http://test.org#> .
> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
> 
> [ruleDeadlinePassed:
> (?ev ns:hasDeadline ?date)
> now(?now)
> greaterThan(?now, ?date)
> ->
> (?ev ns:hasStatus ns:Status_DeadlinePassed)
> ]
> ### END RULE ###
> 
> 
> 
> From: Pierre Grenon
> Sent: 22 May 2019 17:06
> To: 'users@jena.apache.org'
> Subject: RE: Documentation/tutorial on using dates in Jena rules with
> GenericRuleReasoner
> 
> Hi – yes, it works for me using fuseki as well. Apologies, I think my config file
> was bad or the data somehow.
> 
> For reference, similar to your test:
> 
> - Conference_GRR_onerule.ttl --- fuseki config with TDB2 and generic rule
> reasoner
> - conference1.ttl --- small test set, with more than minimal data
> - conference1.rules --- single (same) rule
> 
> Query: select * where {?x <http://test.org#hasStatus> ?z}
> 
> 
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 18 May 2019 19:12
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with
> GenericRuleReasoner
> 
> 
> > b. I think I actually tried the rule below and I didn’t get any inference
> result. Don’t know if it’s my config, my rule or my data. I could start a. by
> trying to provide a dataset and config file as well. Again, anybody willing to
> hold my hand?
> 
> Works for me as expected:
> 
> |    Model m = ModelFactory.createDefaultModel();||
> ||    String s = "@prefix ns: <http://test.org/> .\n" +||
> ||               "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n" +||
> ||               "<s> ns:hasDeadline
> \"2002-05-30T09:00:00\"^^xsd:dateTime .";||||
> ||    m.read(new StringReader(s), null, "Turtle");||
> ||
> ||    String rule =||
> ||            " [ruleMissedDeadline2: (?conference
> <http://test.org/hasDeadline> ?date) now(?now) greaterThan(?now, ?date)
> " +||
> ||                    "-> (?conference <http://test.org/status>
> <http://test.org/DeadlinePassed>)]";||
> ||
> ||    List rules = Rule.parseRules(rule);||
> ||    Reasoner reasoner = new GenericRuleReasoner(rules);||
> ||    Model infModel = ModelFactory.createInfModel(reasoner, m);||
> ||    infModel.write(System.out, "N-Triples");|
> 
> 
> 
> > Give a shout.
> >
> > Thanks,
> > Pierre
> >
> > From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> > Sent: 17 May 2019 07:24
> > To: users@jena.apache.org
> > Subject: Re: Documentation/tutorial on using dates in Jena rules with
> GenericRuleReasoner
> >
> > Hi,
> >
> >> Hi Lorenz,
> >>
> >> Thank you for your answer.
> >>
> >> Quick follow up.
> >>
> >> I think the issue for me is the documentation of the built-ins is too
> abstract or relies on understanding the source code. So I suppose,
> documentation / tutorial seems somewhat superfluous when you can do
> that – only I can’t understand what’s there and the source at the moment.
> > I can see that it might be too abstract for people coming from different
> > areas, sure. But, the question is who is able to provide such a tutorial
> > and also who has the time. It's always a trade-off in Open Source
> > projects like Jena - I guess most of the devs or other project related
> > people here are not getting payed, and clearly such a tutorial for most
> > if not all of the built-ins definitely needs some effort. Ideally, the
> > community could take over those things, but looks like nobody ever wrote
> > blog posts or tutorials about the Jena rule system and its built-ins.
> >>
> >>
> >> 1. Yes, I seem to understand difference is a no go but I was wondering if
> there might be some work around coercing the dateTime to something else.
> I’m not sure I understood that very well but it looks like I can’t use functions
> in arguments of built-ins (so no xsd:year(?date) or whatever).
> > I don't think you can use functions or expressions from the SPARQL
> > engine resp. its XPath constructors. Both are totally different
> > implementations I guess - but again, I'm not a developer, so I can't
> > make a valid statement, except for looking into the code and the docs.
> > From my point of view, only the mentioned built-ins from the docs are
> > valid so far.
> >>
> >>
> >> But then, on greaterThan, something should be workable if I have
> xsd:dateTime, no?
> >>
> >> What’s wrong with :
> >>
> >>
> >>
> >> [ruleMissedDeadline2:
> >>
> >> (?conference ns:hasDeadline ?date)
> >>
> >> now(?now)
> >>
> >> greaterThan(?now, ?date)
> >>
> >> ->
> >>
> >> (?conference ns:status ns:DeadlinePassed)
> >>
> >> ]
> > Well I was clearly thinking too complicated, so yes, your rule should
> > work given that the docs say
> >
> >> lessThan(?x, ?y), greaterThan(?x, ?y)
> >> le(?x, ?y), ge(?x, ?y)
> >>
> >> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
> >> or time instants (can be integer or floating point or XSDDateTime).
> > I was more thinking about things like inferring the age of a person
> > isn't possible right now, but would clearly be some nice to have feature
> > such that you could have it as implicit fact in your KB without the need
> > to change the asserted data every year.
> >
> >> 2. When you say extend the rule system, you mean adding a class using as
> a starting point something is in ..rulesys.builtins and adapting it and then
> rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah?
> Aside from the fact I’m not coding in java, this isn’t the easiest path for me
> at the moment.
> > That's also something I can't answer properly. I mean, yes, you can
> > create custom built-ins and register those or maybe create an overriding
> > registry [1] ? But not sure, it looks like at least the overriding
> > registry would have to be used by the rule parser, so I don't know how
> > you would have to combine it with Fuseki. And in the end, yes, you have
> > to repackage Fuseki I think as long as you modify the existing
> > BuiltinRegistry.
> >
> > Maybe there is also some other kind of plugin system here, but that can
> > only be answered by Andy, Dave, Adam, etc.
> >
> >
> > [1] https://issues.apache.org/jira/browse/JENA-
> 1204<https://issues.apache.org/jira/browse/JENA-1204>
> >
> >> Many thanks,
> >> Pierre
> >>
> >>
> >> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> >> Sent: 16 May 2019 08:33
> >> To: users@jena.apache.org
> >> Subject: Re: Documentation/tutorial on using dates in Jena rules with
> GenericRuleReasoner
> >>
> >> I'm not aware of any tutorial, but afaik you can't do what you did here
> >> with SPARQL in Jena rules without writing custom built-ins or by
> >> extending the existing ones because:
> >>
> >> * the "difference" built-in does only work for numbers right now [1]
> >>
> >> * there is no support for duration type at all it looks like
> >>
> >>
> >> So, so far you could only compare datetime values via lessThan, le,
> >> greaterThan, ge but there is no other built-in with support for date
> >> values so far. Others might indeed correct me if I'm wrong of.
> >>
> >>
> >> It looks like, you have to extend the rule system by custom built-ins -
> >> it's not that difficult though [2]
> >>
> >> [1]
> >> https://github.com/apache/jena/blob/master/jena-
> core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.ja
> va#L68<https://github.com/apache/jena/blob/master/jena-
> core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.ja
> va#L68><https://github.com/apache/jena/blob/master/jena-
> core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.ja
> va#L68<https://github.com/apache/jena/blob/master/jena-
> core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.ja
> va#L68>>
> >> [2]
> https://jena.apache.org/documentation/inference/#builtins<https://jena.ap
> ache.org/documentation/inference/#builtins><https://jena.apache.org/docu
> mentation/inference/#builtins<https://jena.apache.org/documentation/infe
> rence/#builtins>>
> >>
> >>> Could people recommend a good reference/tutorial on how to use built-
> ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration
> and so on) in rules for the GenericRuleReasoner?
> >>>
> >>> Example:
> >>>
> >>> Assume a KB of conferences with their deadlines as xsd:dateTime.
> >>>
> >>> Here are examples of SPARQL queries to find conferences whose
> deadlines are passed:
> >>>
> >>> SELECT * WHERE {
> >>> ?subject here:hasDeadline ?date .
> >>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
> >>> FILTER(?Span < "P0D"^^xsd:duration)
> >>> }
> >>>
> >>> SELECT * WHERE {
> >>> ?subject here:hasDeadline ?date .
> >>> FILTER(now() > xsd:dateTime(?date))
> >>> }
> >>>
> >>> Suppose instead I wanted to infer some attribute of the conference, e.g:
> >>>
> >>> ?subject here:hasStatus here:DeadlinePassed
> >>>
> >>> I don't really get how to do that in a rule and I can't quite figure if I'm
> misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when
> trying to coerce variables to datatypes).
> >>>
> >>> There's a bunch of recurring questions around that sort of rules but I
> can't quite find any answer that's giving clear examples.
> >>>
> >>> Thus I would find it useful if anybody could point at a resource that goes
> through some sort of how to do date comparison and use that in rules as
> the Jena doc on built-in is not self-contained in that respect.
> >>>
> >>>
> https://jena.apache.org/documentation/inference/#rules<https://jena.apach
> e.org/documentation/inference/#rules><https://jena.apache.org/documenta
> tion/inference/#rules<https://jena.apache.org/documentation/inference/#ru
> les>>
> >>>
> >>>
> >>> With many thanks and kind regards,
> >>> Pierre
> >>>
> >> --
> >> Lorenz Bühmann

RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
Hi – yes, it works for me using fuseki as well. Apologies, I think my config file was bad or the data somehow.

For reference, similar to your test:


-        Conference_GRR_onerule.ttl --- fuseki config with TDB2 and generic rule reasoner

-        conference1.ttl --- small test set, with more than minimal data

-        conference1.rules --- single (same) rule

Query: select * where {?x <http://test.org#hasStatus> ?z}


From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
Sent: 18 May 2019 19:12
To: users@jena.apache.org
Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner


> b. I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?

Works for me as expected:

|    Model m = ModelFactory.createDefaultModel();||
||    String s = "@prefix ns: <http://test.org/<http://test.org/>> .\n" +||
||               "@prefix xsd: <http://www.w3.org/2001/XMLSchema#<http://www.w3.org/2001/XMLSchema#>> .\n" +||
||               "<s> ns:hasDeadline
\"2002-05-30T09:00:00\"^^xsd:dateTime .";||||
||    m.read(new StringReader(s), null, "Turtle");||
||
||    String rule =||
||            " [ruleMissedDeadline2: (?conference
<http://test.org/hasDeadline<http://test.org/hasDeadline>> ?date) now(?now) greaterThan(?now, ?date)
" +||
||                    "-> (?conference <http://test.org/status<http://test.org/status>>
<http://test.org/DeadlinePassed<http://test.org/DeadlinePassed>>)]";||
||
||    List rules = Rule.parseRules(rule);||
||    Reasoner reasoner = new GenericRuleReasoner(rules);||
||    Model infModel = ModelFactory.createInfModel(reasoner, m);||
||    infModel.write(System.out, "N-Triples");|



> Give a shout.
>
> Thanks,
> Pierre
>
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 17 May 2019 07:24
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>
> Hi,
>
>> Hi Lorenz,
>>
>> Thank you for your answer.
>>
>> Quick follow up.
>>
>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
> I can see that it might be too abstract for people coming from different
> areas, sure. But, the question is who is able to provide such a tutorial
> and also who has the time. It's always a trade-off in Open Source
> projects like Jena - I guess most of the devs or other project related
> people here are not getting payed, and clearly such a tutorial for most
> if not all of the built-ins definitely needs some effort. Ideally, the
> community could take over those things, but looks like nobody ever wrote
> blog posts or tutorials about the Jena rule system and its built-ins.
>>
>>
>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
> I don't think you can use functions or expressions from the SPARQL
> engine resp. its XPath constructors. Both are totally different
> implementations I guess - but again, I'm not a developer, so I can't
> make a valid statement, except for looking into the code and the docs.
> From my point of view, only the mentioned built-ins from the docs are
> valid so far.
>>
>>
>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>
>> What’s wrong with :
>>
>>
>>
>> [ruleMissedDeadline2:
>>
>> (?conference ns:hasDeadline ?date)
>>
>> now(?now)
>>
>> greaterThan(?now, ?date)
>>
>> ->
>>
>> (?conference ns:status ns:DeadlinePassed)
>>
>> ]
> Well I was clearly thinking too complicated, so yes, your rule should
> work given that the docs say
>
>> lessThan(?x, ?y), greaterThan(?x, ?y)
>> le(?x, ?y), ge(?x, ?y)
>>
>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>> or time instants (can be integer or floating point or XSDDateTime).
> I was more thinking about things like inferring the age of a person
> isn't possible right now, but would clearly be some nice to have feature
> such that you could have it as implicit fact in your KB without the need
> to change the asserted data every year.
>
>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
> That's also something I can't answer properly. I mean, yes, you can
> create custom built-ins and register those or maybe create an overriding
> registry [1] ? But not sure, it looks like at least the overriding
> registry would have to be used by the rule parser, so I don't know how
> you would have to combine it with Fuseki. And in the end, yes, you have
> to repackage Fuseki I think as long as you modify the existing
> BuiltinRegistry.
>
> Maybe there is also some other kind of plugin system here, but that can
> only be answered by Andy, Dave, Adam, etc.
>
>
> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204><https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>>
>
>> Many thanks,
>> Pierre
>>
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 16 May 2019 08:33
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> I'm not aware of any tutorial, but afaik you can't do what you did here
>> with SPARQL in Jena rules without writing custom built-ins or by
>> extending the existing ones because:
>>
>> * the "difference" built-in does only work for numbers right now [1]
>>
>> * there is no support for duration type at all it looks like
>>
>>
>> So, so far you could only compare datetime values via lessThan, le,
>> greaterThan, ge but there is no other built-in with support for date
>> values so far. Others might indeed correct me if I'm wrong of.
>>
>>
>> It looks like, you have to extend the rule system by custom built-ins -
>> it's not that difficult though [2]
>>
>> [1]
>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>>
>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>>
>>
>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>
>>> Example:
>>>
>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>
>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>> FILTER(?Span < "P0D"^^xsd:duration)
>>> }
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> FILTER(now() > xsd:dateTime(?date))
>>> }
>>>
>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>
>>> ?subject here:hasStatus here:DeadlinePassed
>>>
>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>
>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>
>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>
>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>>
>>>
>>>
>>> With many thanks and kind regards,
>>> Pierre
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>><http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>>> - semantic web research center
>>
>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>
>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html><https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>>)
>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/><https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>>.
>>
>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>> - semantic web research center
>
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>.
>
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
>
>
--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org<http://aksw.org> - semantic web research center

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.



RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
Apologies for repost -- it *feels* like attaching stuff to emails is not the right thing to do. So, for all it's worth, as I would find it useful myself, files copied below. 

Many thanks, 
Pierre



- Conference_GRR_onerule.ttl --- fuseki config with TDB2 and generic rule reasoner
### START CONFIG ###

@prefix :      <http://base/#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix tdb2:  <http://jena.apache.org/2016/tdb#> .
@prefix ja:    <http://jena.hpl.hp.com/2005/11/Assembler#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .

:theService a                   fuseki:Service ;
        rdfs:label                    "Service with update and query to test minimal dataset with inference using an instance of generic rule reasoner" ;
        fuseki:dataset                :theDataset ;
		#:tdb_dataset_readwrite ;
        fuseki:name                   "Conference1" ;
        fuseki:serviceQuery           "query" , "sparql" ;
        fuseki:serviceReadGraphStore  "get" ;
        fuseki:serviceReadWriteGraphStore
                "data" ;
        fuseki:serviceUpdate          "update" ;
        fuseki:serviceUpload          "upload" .

:theDataset a ja:RDFDataset ; 
    ja:defaultGraph <#theModel_GRR> .
		
<#theModel_GRR> a ja:InfModel ;
    ja:baseModel <#theGraph> ;
	ja:reasoner [
		ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ;
		ja:rulesFrom <file:///C:/dev/apache-jena-fuseki-3.10.0/data/conference/conference1.rules> 
	] ;
.
		
<#theGraph> rdf:type tdb2:GraphTDB ;
   tdb2:dataset :theTDB2Dataset .
		
:theTDB2Dataset
        a              tdb2:DatasetTDB2 ;
        tdb2:location  "C:\\dev\\apache-jena-fuseki-3.10.0\\run/databases/Conference1" ;
		tdb2:unionDefaultGraph true.

### END CONFIG ###

- conference1.ttl 
### START DATA ###

@prefix : <http://test.org#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

### OE
<http://test.org#OrganisedEvent> rdf:type owl:Class ;
	rdfs:label "organised event" .

<http://test.org#Conference> rdf:type owl:Class ;
	rdfs:subClassOf <http://test.org#OrganisedEvent> ;
	rdfs:label "conference" .
	
<http://test.org#Workshop> rdf:type owl:Class ; 
	rdfs:subClassOf <http://test.org#OrganisedEvent> ;
	rdfs:label "workshop" .

<http://test.org#hasDeadline> rdf:type owl:DatatypeProperty ;
	rdfs:domain <http://test.org#OrganisedEvent> ;
	rdfs:range xsd:dateTime ;
	rdfs:label "deadline passed" .
	
<http://test.org#Status> rdf:type owl:Class ; 
	rdfs:label "Status" .

<http://test.org#hasStatus> 
	rdf:type owl:ObjectProperty ;
	rdfs:domain <http://test.org#OrganisedEvent> ;
	rdfs:range <http://test.org#Status> ;
	rdfs:label "has status" .

<http://test.org#Status_DeadlinePassed> 
	rdf:type owl:NamedIndividual , <http://test.org#Status> ;
	rdfs:label "deadline passed" .
	
<http://test.org#Status_DeadlineActive> 
	rdf:type owl:NamedIndividual , <http://test.org#Status> ;
	rdfs:label "deadline active" .

	
### KB
<http://test.org#Conference1> rdf:type owl:NamedIndividual , <http://test.org#Conference> ;
	<http://test.org#hasDeadline>"2019-01-01T00:00:00Z"^^xsd:dateTime ;
	rdfs:label "1st Intl Conf of the Penguin Appreciation Society" .

<http://test.org#Conference2> rdf:type owl:NamedIndividual , <http://test.org#Conference> ;
	<http://test.org#hasDeadline>"3019-01-01T00:00:00Z"^^xsd:dateTime ;
	rdfs:label "101st Conf of the Penguin Appreciation Society" .

<http://test.org#Workshop1> rdf:type owl:NamedIndividual , <http://test.org#Workshop> ;
	<http://test.org#hasDeadline>"2018-07-01T00:00:00Z"^^xsd:dateTime ;
	rdfs:label "How to walk like a penguin" .

<http://test.org#Workshop2> rdf:type owl:NamedIndividual , <http://test.org#Workshop> ;
	<http://test.org#hasDeadline>"2030-07-01T00:00:00Z"^^xsd:dateTime ;
	rdfs:label "Do penguins walk?" .
	
### END DATA ###

- conference1.rules 
### START RULE###
@prefix ns: <http://test.org#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

[ruleDeadlinePassed: 
(?ev ns:hasDeadline ?date)
now(?now)
greaterThan(?now, ?date)
-> 
(?ev ns:hasStatus ns:Status_DeadlinePassed)
]
### END RULE ###



From: Pierre Grenon 
Sent: 22 May 2019 17:06
To: 'users@jena.apache.org'
Subject: RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Hi – yes, it works for me using fuseki as well. Apologies, I think my config file was bad or the data somehow. 

For reference, similar to your test: 

- Conference_GRR_onerule.ttl --- fuseki config with TDB2 and generic rule reasoner
- conference1.ttl --- small test set, with more than minimal data
- conference1.rules --- single (same) rule 

Query: select * where {?x <http://test.org#hasStatus> ?z}


From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de] 
Sent: 18 May 2019 19:12
To: users@jena.apache.org
Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner


> b. I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.


Works for me as expected:

|    Model m = ModelFactory.createDefaultModel();||
||    String s = "@prefix ns: <http://test.org/> .\n" +||
||               "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n" +||
||               "<s> ns:hasDeadline
\"2002-05-30T09:00:00\"^^xsd:dateTime .";||||
||    m.read(new StringReader(s), null, "Turtle");||
||
||    String rule =||
||            " [ruleMissedDeadline2: (?conference
<http://test.org/hasDeadline> ?date) now(?now) greaterThan(?now, ?date)
" +||
||                    "-> (?conference <http://test.org/status>
<http://test.org/DeadlinePassed>)]";||
||
||    List rules = Rule.parseRules(rule);||
||    Reasoner reasoner = new GenericRuleReasoner(rules);||
||    Model infModel = ModelFactory.createInfModel(reasoner, m);||
||    infModel.write(System.out, "N-Triples");|



> Give a shout.
>
> Thanks,
> Pierre
>
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 17 May 2019 07:24
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>
> Hi,
>
>> Hi Lorenz,
>>
>> Thank you for your answer.
>>
>> Quick follow up.
>>
>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
> I can see that it might be too abstract for people coming from different
> areas, sure. But, the question is who is able to provide such a tutorial
> and also who has the time. It's always a trade-off in Open Source
> projects like Jena - I guess most of the devs or other project related
> people here are not getting payed, and clearly such a tutorial for most
> if not all of the built-ins definitely needs some effort. Ideally, the
> community could take over those things, but looks like nobody ever wrote
> blog posts or tutorials about the Jena rule system and its built-ins.
>>
>>
>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
> I don't think you can use functions or expressions from the SPARQL
> engine resp. its XPath constructors. Both are totally different
> implementations I guess - but again, I'm not a developer, so I can't
> make a valid statement, except for looking into the code and the docs.
> From my point of view, only the mentioned built-ins from the docs are
> valid so far.
>>
>>
>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>
>> What’s wrong with :
>>
>>
>>
>> [ruleMissedDeadline2:
>>
>> (?conference ns:hasDeadline ?date)
>>
>> now(?now)
>>
>> greaterThan(?now, ?date)
>>
>> ->
>>
>> (?conference ns:status ns:DeadlinePassed)
>>
>> ]
> Well I was clearly thinking too complicated, so yes, your rule should
> work given that the docs say
>
>> lessThan(?x, ?y), greaterThan(?x, ?y)
>> le(?x, ?y), ge(?x, ?y)
>>
>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>> or time instants (can be integer or floating point or XSDDateTime).
> I was more thinking about things like inferring the age of a person
> isn't possible right now, but would clearly be some nice to have feature
> such that you could have it as implicit fact in your KB without the need
> to change the asserted data every year.
>
>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
> That's also something I can't answer properly. I mean, yes, you can
> create custom built-ins and register those or maybe create an overriding
> registry [1] ? But not sure, it looks like at least the overriding
> registry would have to be used by the rule parser, so I don't know how
> you would have to combine it with Fuseki. And in the end, yes, you have
> to repackage Fuseki I think as long as you modify the existing
> BuiltinRegistry.
>
> Maybe there is also some other kind of plugin system here, but that can
> only be answered by Andy, Dave, Adam, etc.
>
>
> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>
>
>> Many thanks,
>> Pierre
>>
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 16 May 2019 08:33
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> I'm not aware of any tutorial, but afaik you can't do what you did here
>> with SPARQL in Jena rules without writing custom built-ins or by
>> extending the existing ones because:
>>
>> * the "difference" built-in does only work for numbers right now [1]
>>
>> * there is no support for duration type at all it looks like
>>
>>
>> So, so far you could only compare datetime values via lessThan, le,
>> greaterThan, ge but there is no other built-in with support for date
>> values so far. Others might indeed correct me if I'm wrong of.
>>
>>
>> It looks like, you have to extend the rule system by custom built-ins -
>> it's not that difficult though [2]
>>
>> [1]
>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>>
>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>
>>> Example:
>>>
>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>
>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>> FILTER(?Span < "P0D"^^xsd:duration)
>>> }
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> FILTER(now() > xsd:dateTime(?date))
>>> }
>>>
>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>
>>> ?subject here:hasStatus here:DeadlinePassed
>>>
>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>
>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>
>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>
>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>>
>>>
>>> With many thanks and kind regards,
>>> Pierre
>>>
>> --
>> Lorenz Bühmann

Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by "Lorenz B." <bu...@informatik.uni-leipzig.de>.
> b.      I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?

Works for me as expected:

|    Model m = ModelFactory.createDefaultModel();||
||    String s = "@prefix ns: <http://test.org/> .\n" +||
||               "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n" +||
||               "<s> ns:hasDeadline
\"2002-05-30T09:00:00\"^^xsd:dateTime .";||||
||    m.read(new StringReader(s), null, "Turtle");||
||
||    String rule =||
||            " [ruleMissedDeadline2: (?conference
<http://test.org/hasDeadline> ?date) now(?now) greaterThan(?now, ?date)
" +||
||                    "-> (?conference <http://test.org/status>
<http://test.org/DeadlinePassed>)]";||
||
||    List rules = Rule.parseRules(rule);||
||    Reasoner reasoner = new GenericRuleReasoner(rules);||
||    Model infModel = ModelFactory.createInfModel(reasoner, m);||
||    infModel.write(System.out, "N-Triples");|



> Give a shout.
>
> Thanks,
> Pierre
>
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 17 May 2019 07:24
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>
> Hi,
>
>> Hi Lorenz,
>>
>> Thank you for your answer.
>>
>> Quick follow up.
>>
>> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
> I can see that it might be too abstract for people coming from different
> areas, sure. But, the question is who is able to provide such a tutorial
> and also who has the time. It's always a trade-off in Open Source
> projects like Jena - I guess most of the devs or other project related
> people here are not getting payed, and clearly such a tutorial for most
> if not all of the built-ins definitely needs some effort. Ideally, the
> community could take over those things, but looks like nobody ever wrote
> blog posts or tutorials about the Jena rule system and its built-ins.
>>
>>
>> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
> I don't think you can use functions or expressions from the SPARQL
> engine resp. its XPath constructors. Both are totally different
> implementations I guess - but again, I'm not a developer, so I can't
> make a valid statement, except for looking into the code and the docs.
> From my point of view, only the mentioned built-ins from the docs are
> valid so far.
>>
>>
>> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>>
>> What’s wrong with :
>>
>>
>>
>> [ruleMissedDeadline2:
>>
>> (?conference ns:hasDeadline ?date)
>>
>> now(?now)
>>
>> greaterThan(?now, ?date)
>>
>> ->
>>
>> (?conference ns:status ns:DeadlinePassed)
>>
>> ]
> Well I was clearly thinking too complicated, so yes, your rule should
> work given that the docs say
>
>> lessThan(?x, ?y), greaterThan(?x, ?y)
>> le(?x, ?y), ge(?x, ?y)
>>
>> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
>> or time instants (can be integer or floating point or XSDDateTime).
> I was more thinking about things like inferring the age of a person
> isn't possible right now, but would clearly be some nice to have feature
> such that you could have it as implicit fact in your KB without the need
> to change the asserted data every year.
>
>> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.
> That's also something I can't answer properly. I mean, yes, you can
> create custom built-ins and register those or maybe create an overriding
> registry [1] ? But not sure, it looks like at least the overriding
> registry would have to be used by the rule parser, so I don't know how
> you would have to combine it with Fuseki. And in the end, yes, you have
> to repackage Fuseki I think as long as you modify the existing
> BuiltinRegistry.
>
> Maybe there is also some other kind of plugin system here, but that can
> only be answered by Andy, Dave, Adam, etc.
>
>
> [1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>
>
>> Many thanks,
>> Pierre
>>
>>
>> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
>> Sent: 16 May 2019 08:33
>> To: users@jena.apache.org
>> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>>
>> I'm not aware of any tutorial, but afaik you can't do what you did here
>> with SPARQL in Jena rules without writing custom built-ins or by
>> extending the existing ones because:
>>
>> * the "difference" built-in does only work for numbers right now [1]
>>
>> * there is no support for duration type at all it looks like
>>
>>
>> So, so far you could only compare datetime values via lessThan, le,
>> greaterThan, ge but there is no other built-in with support for date
>> values so far. Others might indeed correct me if I'm wrong of.
>>
>>
>> It looks like, you have to extend the rule system by custom built-ins -
>> it's not that difficult though [2]
>>
>> [1]
>> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
>> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>>
>>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>>
>>> Example:
>>>
>>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>>
>>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>>> FILTER(?Span < "P0D"^^xsd:duration)
>>> }
>>>
>>> SELECT * WHERE {
>>> ?subject here:hasDeadline ?date .
>>> FILTER(now() > xsd:dateTime(?date))
>>> }
>>>
>>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>>
>>> ?subject here:hasStatus here:DeadlinePassed
>>>
>>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>>
>>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>>
>>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>>
>>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>>
>>>
>>> With many thanks and kind regards,
>>> Pierre
>>>
>> --
>> Lorenz Bühmann
>> AKSW group, University of Leipzig
>> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>> - semantic web research center
>>
>> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
>> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
>> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
>> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
>> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>>
>> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
>> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
>> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
>> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
>> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
>> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
>> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>)
>> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
>> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
>> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
>> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>.
>>
>> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
>> BY THE FINANCIAL CONDUCT AUTHORITY.
>>
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org<http://aksw.org> - semantic web research center
>
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 
>
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 
>
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
> BY THE FINANCIAL CONDUCT AUTHORITY.
>
>
-- 
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org - semantic web research center


RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
Hi

Thanks again.

Hear you.

I think this is becoming a bit too meta perhaps. Maybe there’s a couple of ways to go forward.


a.      Anybody is a taker to hold me by the hand and use this thread to come up with a complete cycle for making a new built in and adding it to my fuseki? If somebody has the time to do this---and I’m happy that it takes what it takes, I can’t on my end make it a high priority--, we could reuse the thread for the purpose of a detailed how-to for noobs like me.

b.      I think I actually tried the rule below and I didn’t get any inference result. Don’t know if it’s my config, my rule or my data. I could start a. by trying to provide a dataset and config file as well. Again, anybody willing to hold my hand?

Give a shout.

Thanks,
Pierre

From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
Sent: 17 May 2019 07:24
To: users@jena.apache.org
Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Hi,

> Hi Lorenz,
>
> Thank you for your answer.
>
> Quick follow up.
>
> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
I can see that it might be too abstract for people coming from different
areas, sure. But, the question is who is able to provide such a tutorial
and also who has the time. It's always a trade-off in Open Source
projects like Jena - I guess most of the devs or other project related
people here are not getting payed, and clearly such a tutorial for most
if not all of the built-ins definitely needs some effort. Ideally, the
community could take over those things, but looks like nobody ever wrote
blog posts or tutorials about the Jena rule system and its built-ins.
>
>
>
> 1. Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
I don't think you can use functions or expressions from the SPARQL
engine resp. its XPath constructors. Both are totally different
implementations I guess - but again, I'm not a developer, so I can't
make a valid statement, except for looking into the code and the docs.
From my point of view, only the mentioned built-ins from the docs are
valid so far.
>
>
>
> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>
> What’s wrong with :
>
>
>
> [ruleMissedDeadline2:
>
> (?conference ns:hasDeadline ?date)
>
> now(?now)
>
> greaterThan(?now, ?date)
>
> ->
>
> (?conference ns:status ns:DeadlinePassed)
>
> ]

Well I was clearly thinking too complicated, so yes, your rule should
work given that the docs say

> lessThan(?x, ?y), greaterThan(?x, ?y)
> le(?x, ?y), ge(?x, ?y)
>
> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
> or time instants (can be integer or floating point or XSDDateTime).
I was more thinking about things like inferring the age of a person
isn't possible right now, but would clearly be some nice to have feature
such that you could have it as implicit fact in your KB without the need
to change the asserted data every year.

>
> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.

That's also something I can't answer properly. I mean, yes, you can
create custom built-ins and register those or maybe create an overriding
registry [1] ? But not sure, it looks like at least the overriding
registry would have to be used by the rule parser, so I don't know how
you would have to combine it with Fuseki. And in the end, yes, you have
to repackage Fuseki I think as long as you modify the existing
BuiltinRegistry.

Maybe there is also some other kind of plugin system here, but that can
only be answered by Andy, Dave, Adam, etc.


[1] https://issues.apache.org/jira/browse/JENA-1204<https://issues.apache.org/jira/browse/JENA-1204>

>
> Many thanks,
> Pierre
>
>
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 16 May 2019 08:33
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>
> I'm not aware of any tutorial, but afaik you can't do what you did here
> with SPARQL in Jena rules without writing custom built-ins or by
> extending the existing ones because:
>
> * the "difference" built-in does only work for numbers right now [1]
>
> * there is no support for duration type at all it looks like
>
>
> So, so far you could only compare datetime values via lessThan, le,
> greaterThan, ge but there is no other built-in with support for date
> values so far. Others might indeed correct me if I'm wrong of.
>
>
> It looks like, you have to extend the rule system by custom built-ins -
> it's not that difficult though [2]
>
> [1]
> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68><https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>>
> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins><https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>>
>
>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>
>> Example:
>>
>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>
>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>
>> SELECT * WHERE {
>> ?subject here:hasDeadline ?date .
>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>> FILTER(?Span < "P0D"^^xsd:duration)
>> }
>>
>> SELECT * WHERE {
>> ?subject here:hasDeadline ?date .
>> FILTER(now() > xsd:dateTime(?date))
>> }
>>
>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>
>> ?subject here:hasStatus here:DeadlinePassed
>>
>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>
>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>
>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>
>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules><https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>>
>>
>>
>> With many thanks and kind regards,
>> Pierre
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org<http://aksw.org><http://aksw.org<http://aksw.org>> - semantic web research center
>
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION.
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN.
>
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014).
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html<https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html>)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS,
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/<https://www.horizon-asset.co.uk/market-soundings/>.
>
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED
> BY THE FINANCIAL CONDUCT AUTHORITY.
>
>
--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org<http://aksw.org> - semantic web research center

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.



Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by "Lorenz B." <bu...@informatik.uni-leipzig.de>.
Hi,

> Hi Lorenz,
>
> Thank you for your answer.
>
> Quick follow up.
>
> I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.
I can see that it might be too abstract for people coming from different
areas, sure. But, the question is who is able to provide such a tutorial
and also who has the time. It's always a trade-off in Open Source
projects like Jena - I guess most of the devs or other project related
people here are not getting payed, and clearly such a tutorial for most
if not all of the built-ins definitely needs some effort. Ideally, the
community could take over those things, but looks like nobody ever wrote
blog posts or tutorials about the Jena rule system and its built-ins.
>
>
>
> 1.      Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).
I don't think you can use functions or expressions from the SPARQL
engine resp. its XPath constructors. Both are totally different
implementations I guess - but again, I'm not a developer, so I can't
make a valid statement, except for looking into the code and the docs.
From my point of view, only the mentioned built-ins from the docs are
valid so far.
>
>
>
> But then, on greaterThan, something should be workable if I have xsd:dateTime, no?
>
> What’s wrong with :
>
>
>
> [ruleMissedDeadline2:
>
> (?conference ns:hasDeadline ?date)
>
> now(?now)
>
> greaterThan(?now, ?date)
>
> ->
>
> (?conference ns:status ns:DeadlinePassed)
>
> ]

Well I was clearly thinking too complicated, so yes, your rule should
work given that the docs say

> lessThan(?x, ?y), greaterThan(?x, ?y)
> le(?x, ?y), ge(?x, ?y)
>
> Test if x is <, >, <= or >= y. Only passes if both x and y are numbers
> or time instants (can be integer or floating point or XSDDateTime).
I was more thinking about things like inferring the age of a person
isn't possible right now, but would clearly be some nice to have feature
such that you could have it as implicit fact in your KB without the need
to change the asserted data every year.

>
> 2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.

That's also something I can't answer properly. I mean, yes, you can
create custom built-ins and register those or maybe create an overriding
registry [1] ? But not sure, it looks like at least the overriding
registry would have to be used by the rule parser, so I don't know how
you would have to combine it with Fuseki. And in the end, yes, you have
to repackage Fuseki I think as long as you modify the existing
BuiltinRegistry.

Maybe there is also some other kind of plugin system here, but that can
only be answered by Andy, Dave, Adam, etc.


[1] https://issues.apache.org/jira/browse/JENA-1204

>
> Many thanks,
> Pierre
>
>
> From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
> Sent: 16 May 2019 08:33
> To: users@jena.apache.org
> Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner
>
> I'm not aware of any tutorial, but afaik you can't do what you did here
> with SPARQL in Jena rules without writing custom built-ins or by
> extending the existing ones because:
>
> * the "difference" built-in does only work for numbers right now [1]
>
> * there is no support for duration type at all it looks like
>
>
> So, so far you could only compare datetime values via lessThan, le,
> greaterThan, ge but there is no other built-in with support for date
> values so far. Others might indeed correct me if I'm wrong of.
>
>
> It looks like, you have to extend the rule system by custom built-ins -
> it's not that difficult though [2]
>
> [1]
> https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>
> [2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>
>
>> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>>
>> Example:
>>
>> Assume a KB of conferences with their deadlines as xsd:dateTime.
>>
>> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>>
>> SELECT * WHERE {
>> ?subject here:hasDeadline ?date .
>> BIND((xsd:dateTime(?date) - now()) AS ?Span)
>> FILTER(?Span < "P0D"^^xsd:duration)
>> }
>>
>> SELECT * WHERE {
>> ?subject here:hasDeadline ?date .
>> FILTER(now() > xsd:dateTime(?date))
>> }
>>
>> Suppose instead I wanted to infer some attribute of the conference, e.g:
>>
>> ?subject here:hasStatus here:DeadlinePassed
>>
>> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>>
>> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>>
>> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>>
>> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>
>>
>>
>> With many thanks and kind regards,
>> Pierre
>>
> --
> Lorenz Bühmann
> AKSW group, University of Leipzig
> Group: http://aksw.org<http://aksw.org> - semantic web research center
>
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 
>
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 
>
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
> BY THE FINANCIAL CONDUCT AUTHORITY.
>
>
-- 
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org - semantic web research center


RE: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by Pierre Grenon <pg...@horizon-asset.co.uk>.
Hi Lorenz,

Thank you for your answer.

Quick follow up.

I think the issue for me is the documentation of the built-ins is too abstract or relies on understanding the source code. So I suppose, documentation / tutorial seems somewhat superfluous when you can do that – only I can’t understand what’s there and the source at the moment.



1.      Yes, I seem to understand difference is a no go but I was wondering if there might be some work around coercing the dateTime to something else. I’m not sure I understood that very well but it looks like I can’t use functions in arguments of built-ins (so no xsd:year(?date) or whatever).



But then, on greaterThan, something should be workable if I have xsd:dateTime, no?

What’s wrong with :



[ruleMissedDeadline2:

(?conference ns:hasDeadline ?date)

now(?now)

greaterThan(?now, ?date)

->

(?conference ns:status ns:DeadlinePassed)

]

2. When you say extend the rule system, you mean adding a class using as a starting point something is in ..rulesys.builtins and adapting it and then rebuild all the jars. I’m using Fuseki, so I’d have to rebuild that too, yeah? Aside from the fact I’m not coding in java, this isn’t the easiest path for me at the moment.

Many thanks,
Pierre


From: Lorenz B. [mailto:buehmann@informatik.uni-leipzig.de]
Sent: 16 May 2019 08:33
To: users@jena.apache.org
Subject: Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

I'm not aware of any tutorial, but afaik you can't do what you did here
with SPARQL in Jena rules without writing custom built-ins or by
extending the existing ones because:

* the "difference" built-in does only work for numbers right now [1]

* there is no support for duration type at all it looks like


So, so far you could only compare datetime values via lessThan, le,
greaterThan, ge but there is no other built-in with support for date
values so far. Others might indeed correct me if I'm wrong of.


It looks like, you have to extend the rule system by custom built-ins -
it's not that difficult though [2]

[1]
https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68<https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68>
[2] https://jena.apache.org/documentation/inference/#builtins<https://jena.apache.org/documentation/inference/#builtins>

> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>
> Example:
>
> Assume a KB of conferences with their deadlines as xsd:dateTime.
>
> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>
> SELECT * WHERE {
> ?subject here:hasDeadline ?date .
> BIND((xsd:dateTime(?date) - now()) AS ?Span)
> FILTER(?Span < "P0D"^^xsd:duration)
> }
>
> SELECT * WHERE {
> ?subject here:hasDeadline ?date .
> FILTER(now() > xsd:dateTime(?date))
> }
>
> Suppose instead I wanted to infer some attribute of the conference, e.g:
>
> ?subject here:hasStatus here:DeadlinePassed
>
> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes).
>
> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples.
>
> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>
> https://jena.apache.org/documentation/inference/#rules<https://jena.apache.org/documentation/inference/#rules>
>
>
> With many thanks and kind regards,
> Pierre
>

--
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org<http://aksw.org> - semantic web research center

THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 

IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
"THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
(AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
(https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 

HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
BY THE FINANCIAL CONDUCT AUTHORITY.



Re: Documentation/tutorial on using dates in Jena rules with GenericRuleReasoner

Posted by "Lorenz B." <bu...@informatik.uni-leipzig.de>.
I'm not aware of any tutorial, but afaik you can't do what you did here
with SPARQL in Jena rules without writing custom built-ins or by
extending the existing ones because:

* the "difference" built-in does only work for numbers right now [1]

* there is no support for duration type at all it looks like


So, so far you could only compare datetime values via lessThan, le,
greaterThan, ge but there is no other built-in with support for date
values so far. Others might indeed correct me if I'm wrong of.


It looks like, you have to extend the rule system by custom built-ins -
it's not that difficult though [2]

[1]
https://github.com/apache/jena/blob/master/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/builtins/Difference.java#L68
[2] https://jena.apache.org/documentation/inference/#builtins

> Could people recommend a good reference/tutorial on how to use built-ins (greaterThan, difference, now etc) with dates (e.g., datetime, duration and so on) in rules for the GenericRuleReasoner?
>
> Example: 
>
> Assume a KB of conferences with their deadlines as xsd:dateTime. 
>
> Here are examples of SPARQL queries to find conferences whose deadlines are passed:
>
> SELECT * WHERE { 
> 	?subject here:hasDeadline ?date . 
> 	BIND((xsd:dateTime(?date) - now()) AS ?Span)
> 	FILTER(?Span < "P0D"^^xsd:duration)
> 	} 
>
> SELECT * WHERE { 
> 	?subject here:hasDeadline ?date . 
>     	FILTER(now() > xsd:dateTime(?date)) 
> 	}
>
> Suppose instead I wanted to infer some attribute of the conference, e.g: 
>
> ?subject here:hasStatus here:DeadlinePassed 
>
> I don't really get how to do that in a rule and I can't quite figure if I'm misusing the built-ins or just mixing SPARQL and rule syntax (e.g., when trying to coerce variables to datatypes). 
>
> There's a bunch of recurring questions around that sort of rules but I can't quite find any answer that's giving clear examples. 
>
> Thus I would find it useful if anybody could point at a resource that goes through some sort of how to do date comparison and use that in rules as the Jena doc on built-in is not self-contained in that respect.
>
> https://jena.apache.org/documentation/inference/#rules
>
>
> With many thanks and kind regards, 
> Pierre
>
> THIS E-MAIL MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. 
> IF YOU ARE NOT THE INTENDED RECIPIENT (OR HAVE RECEIVED THIS E-MAIL 
> IN ERROR) PLEASE NOTIFY THE SENDER IMMEDIATELY AND DESTROY THIS 
> E-MAIL. ANY UNAUTHORISED COPYING, DISCLOSURE OR DISTRIBUTION OF THE 
> MATERIAL IN THIS E-MAIL IS STRICTLY FORBIDDEN. 
>
> IN ACCORDANCE WITH MIFID II RULES ON INDUCEMENTS, THE FIRM'S EMPLOYEES 
> MAY ATTEND CORPORATE ACCESS EVENTS (DEFINED IN THE FCA HANDBOOK AS 
> "THE SERVICE OF ARRANGING OR BRINGING ABOUT CONTACT BETWEEN AN INVESTMENT 
> MANAGER AND AN ISSUER OR POTENTIAL ISSUER"). DURING SUCH MEETINGS, THE 
> FIRM'S EMPLOYEES MAY ON NO ACCOUNT BE IN RECEIPT OF INSIDE INFORMATION 
> (AS DESCRIBED IN ARTICLE 7 OF THE MARKET ABUSE REGULATION (EU) NO 596/2014). 
> (https://www.handbook.fca.org.uk/handbook/glossary/G3532m.html)
> COMPANIES WHO DISCLOSE INSIDE INFORMATION ARE IN BREACH OF REGULATION 
> AND MUST IMMEDIATELY AND CLEARLY NOTIFY ALL ATTENDEES. FOR INFORMATION 
> ON THE FIRM'S POLICY IN RELATION TO ITS PARTICIPATION IN MARKET SOUNDINGS, 
> PLEASE SEE https://www.horizon-asset.co.uk/market-soundings/. 
>
> HORIZON ASSET LLP IS AUTHORISED AND REGULATED 
> BY THE FINANCIAL CONDUCT AUTHORITY.
>
>
>
-- 
Lorenz Bühmann
AKSW group, University of Leipzig
Group: http://aksw.org - semantic web research center