Is there a way to insert the current date?
You can use the now()
function and cast it to a date with date()
or xsd:date()
.
Jess
Thanks Jess, I have it working but it looks like FILTER doesn’t work in a rule,
WARN 2018-02-25 20:56:17,362 [XNIO-1 task-16] com.complexible.stardog.reasoning.rule.RuleExtractor:parseRule(160): Error parsing rule, ignoring it:
prefix carnot: <http://Carnot.org/>
IF {
?e a carnot:Event .
BIND (now() as ?t) .
FILTER NOT EXISTS { ?e schema:startDate ?z }
}
THEN {
?e schema:startDate ?t
}
java.lang.UnsupportedOperationException: null
Is that expected?
The rule works if I comment out the filter.
The rule you constructed is not allowed. See this section in the documentation Home | Stardog Documentation Latest
"Rule body (IF) and only rule body may optionally contain UNION, BIND or FILTER clauses. However, functions EXISTS, NOT EXISTS, or NOW() cannot be used in rules. User-defined functions (UDF) may be used in rules but if the UDF is not a pure function then the results are undefined."
Okay, thanks.
however, now() seems to work.
It’s a bit of an odd rule. What is your intention? Every time the rule is evaluated it will produce a different value. A rule may be evaluated multiple times within the same query which is the reason it is prohibited.
Jess
I’m using Stardog in my Data Management class at the University of Texas.
This is just for demonstration purposes.
However, if entailments could be materialized, this would be very useful for automatically adding timestamps to events.
Are entailments ever going to be materialized in Stardog?
thanks
phil
Stardog does only support backward-chaining. Just use SPARQL 1.1 Update, i.e. an INSERT
query to modify the data.
But I want a rule to do an insert. I tried,
[] a rule:SPARQLRule;
rule:content """
prefix carnot: <http://Carnot.org/>
IF {
?e a carnot:Employee .
?e carnot:employeeDepartment ?d .
?a carnot:assignmentEmployees ?e .
?a carnot:assignmentPairs ?p
}
THEN {
insert { ?p carnot:pairDepartment ?d }
}
""".
but it gives a syntax error.
prefix carnot: <http://Carnot.org/>
IF {
?e a carnot:Employee .
?e carnot:employeeDepartment ?d .
?a carnot:assignmentEmployees ?e .
?a carnot:assignmentPairs ?p
}
THEN {
insert ( ?p carnot:pairDepartment ?d )
}
Parse error was: Encountered " "insert" "insert "" at line 10, column 3. Was expecting one of: "(" ... "[" ... <NIL> ... <ANON> ...
Rules just don't support doing what you're trying to do. Stardog is very extensible so you might be able to achieve what you're looking to do with a custom trasaction listener. An example can be seen at the stardog-examples repo
And I told you that Stardog doesn’t support forward-chaining (which is materialization) via rules…that’s why I suggested using SPARQL to modify the dataset
Regarding syntax errors, well, you can’t simply write rules in a new language just because you want to have some features.
This can be done fairly straightforward via a regular SPARQL INSERT WHERE query:
prefix carnot: <http://Carnot.org/>
INSERT { ?p carnot:pairDepartment ?d }
WHERE {
?e a carnot:Employee ;
carnot:employeeDepartment ?d .
?a carnot:assignmentEmployees ?e ;
carnot:assignmentPairs ?p
}
Thank you, but this is not a rule. I use sparql all the time to do insert, but I would like to be able to use a rule to do inserts based on something reasoned about the data.
Rules do not do inserts: they only define which triples are true (inferred). It’s up to you to decide what to do with inferred triples. You can insert them into the database (serialize into a file, send over network, etc.):
[] a rule:SPARQLRule;
rule:content """
prefix carnot: <http://Carnot.org/>
IF {
?e a carnot:Employee .
?e carnot:employeeDepartment ?d .
?a carnot:assignmentEmployees ?e .
?a carnot:assignmentPairs ?p
}
THEN {
?p carnot:pairDepartment ?d
}
""".
and then:
prefix carnot: <http://Carnot.org/>
INSERT WHERE { ?p carnot:pairDepartment ?d }
The query should be run with reasoning for the rule to be applied.
Best,
Pavel
I understand this but not allowing rules to do inserts behind the scene without requiring an explicit query is a major deficiency.
Hi Phil,
It looks like what you want is something in the style of production rules whereas Stardog supports logical rules as in Datalog. There are certainly some use cases where production rules are useful since they can be more procedural and use arbitrary functions like now
in your example. However, there are also many documented drawbacks with production rules (typically vague semantics, complexity of rule maintenance as things like priorities and overrides come into play, etc.).
In our experience, Datalog-style declarative rules are much more suitable for the data representation and unification problems that Stardog is used in. And if you have Datalog rules then materialization creates a truth maintenance problem which is why we provide query-time reasoning instead.
Best,
Evren
I understand, I’ve been teaching Data Management and a variety of other “data” courses at the University of Texas for 18 years. I believe this is a major deficiency for a “semantic” data management system, which needs to have a different (better) semantics than relational (datalog) systems. I’d love to discuss how you think Stardog might provide these semantics (automatically) and still preserve its declarative nature if this is possible.
Take this example workflow. I create my .ttl file including the rule and some data:
@prefix rule: <tag:stardog:api:rule:> .
@prefix carnot: <http://Carnot.org/> .
[] a rule:SPARQLRule;
rule:content """
prefix carnot: <http://Carnot.org/>
IF {
?e a carnot:Employee .
?e carnot:employeeDepartment ?d .
?a carnot:assignmentEmployees ?e .
?a carnot:assignmentPairs ?p
}
THEN {
?p carnot:pairDepartment ?d
}
""".
carnot:Employee1 a carnot:Employee ;
rdfs:label "Jim" ;
carnot:employeeDepartment carnot:Department1 .
carnot:Assignment1 carnot:assignmentEmployees carnot:Employee1 ;
carnot:assignmentPairs carnot:Pair1 .
I create a db in Stardog loading this data:
Stephens-iMac:support stephen$ stardog-admin db create -n myDb myDb.ttl
Bulk loading data to new database myDb.
Loaded 7 triples to myDb from 1 file(s) in 00:00:00.290 @ 0.0K triples/sec.
Successfully created database 'myDb'.
Now I can query to prove that the triple from the rule is being inferred properly:
Stephens-iMac:support stephen$ stardog query --reasoning myDb "select * where {?p carnot:pairDepartment ?d}"
+--------------+--------------------+
| p | d |
+--------------+--------------------+
| carnot:Pair1 | carnot:Department1 |
+--------------+--------------------+
Query returned 1 results in 00:00:00.892
Which part of this do you see as deficient? Technically speaking the carnot:Pair1 carnot: carnot:pairDepartment carnot:Department1
isn’t physically on disk, but when performing any read that would need to see it, it would, in practice, always be present.
If I change Jim’s department to Department 2, I want all of the pairings that predated this change to remain as Department1.
If I have the following in file.sparql:
prefix schema: <http://schema.org/>
prefix carnot: <http://Carnot.org/>
insert { ?s ?p ?o }
where {
?s a carnot:Pairing .
?s ?p ?o .
}
;
And I execute the following as follows:
stardog query --reasoning companyDB file.sparql
the insert doesn’t seem to do anything.
However, if I run the following in the Query Panel, the inserts happen:
prefix schema: <http://schema.org/>
prefix carnot: <http://Carnot.org/>
insert { ?s ?p ?o }
where {
?s a carnot:Pairing .
?s ?p ?o .
}
Is there an explanation for this?
thanks
phil