PDDL forall with when condition in durative-action - forall

This question builds on a previous question about forall clauses. I would like to limit the forall with a 'when' statement as shown below:
(:durative-action finish
:parameters (?r - robot ?p - part)
:duration ( = ?duration 1)
:condition (and
(at start (robot_free ?r))
(at start (forall (?f - fastener_loc)
when (part_fastener ?p ?f)
(loc_not_fastened ?f)
)
)
)
:effect (and
(at start(not (robot_free ?r)))
(at end (part_free ?p))
(at end (robot_free ?r))
)
)
This works without the 'when' statement. When I include the 'when' statement, I receive several errors:
Error: Syntax error in durative-action declaration.
Error: Unreadable structure
Error: Syntax error in domain
Thanks in advance for any help.

I was able to get this to work with an imply statement.
(:durative-action finish
:parameters (?r - robot ?p - part)
:duration ( = ?duration 1)
:condition (and
(at start (robot_free ?r))
(at start (forall (?f - fastener_loc)
(imply (part_fastener ?p ?f)(loc_not_fastened ?f))
)
)
)
:effect (and
(at start(not (robot_free ?r)))
(at end (part_free ?p))
(at end (robot_free ?r))
)
)
Not sure if this could also work the the when syntax.

The when clause needs to be wrapped in (brackets)

The when keyword is restricted to conditional effects.
You can see the definition in the PDDL3.1 BNF.
Be a bit careful when combining forall with imply, because it could lead to a nasty combinatorial explosion. Keep in mind that imply typically gets flattened (Negation Normal Form) to a disjunction. So in your case it would become:
(or (not (part_fastener ?p ?f)) (loc_not_fastened ?f))
Which planners typically split into two separate actions (to remove disjunctions), one with (not (part_fastener ?p ?f)) as its precondition, and one with (loc_not_fastened ?f).
The forall then explodes this to all pairwise combinations of the disjunction, to ground it to all instances of fastener_loc, combined with all grounded combinations of robot and part action parameters (to generate the grounded actions themselves).
If you only have a few objects of each type I guess you should be OK.

Related

Error when domain and the problem to use durative-actions

I'm taking the yb_drill_TBM2 example and converting it for use with a time planner (POPF).
I am not able to identify the error can you help me?
DOMAIN:
; Specification in PDDL1 of the rockin TBM2 drill test domain
; author : Oscar Lima, olima_84#yahoo.com
(define (domain idmind_agent)
(:requirements :strips :typing :fluents :negative-preconditions :disjunctive-preconditions :durative-actions )
(:types
location ; locations in the arena, points of interest
robot ; your amazing yet powerful robot
object ; objects to be manipulated by the robot
gripper ; robot gripper
robot_platform ; platform slots for the robot to store objects
)
(:predicates
; robot ?r is at location ?l
(at ?r - robot ?l - location)
; object ?o is on location ?l
(on ?o - object ?l - location)
; object ?o is stored on robot platform ?rp
(stored ?o - object ?rp - robot_platform)
; robot platform ?rp is occupied, yb has 3 free places to store objects
(occupied ?rp - robot_platform)
; gripper ?g is holding object ?o
(holding ?g - gripper ?o - object)
; gripper ?g is free (does not contain object)
(gripper_is_free ?g - gripper)
)
; moves a robot ?r from ?source - location to a ?destination - location
; NOTE : the situation in which the robot arm is in any position before moving
; is not handled at the planning level, hence we advise to always move the arm
; to a folded position, then navigate
(:durative-action move_base
:parameters (?source ?destination - location ?r - robot ?g - gripper)
:duration (= ?duration 1)
:condition (and (at start (at ?r ?source))
(over all (gripper_is_free ?g))
)
:effect (and
(at start (not (at ?r ?source)))
(at end (at ?r ?destination))
)
)
; pick an object ?o which is inside a location ?l with a free gripper ?g
; with robot ?r that is at location ?l
(:durative-action pick
:parameters (?o - object ?l - location ?r - robot ?g - gripper)
:duration (= ?duration 1)
:condition (and (at start (on ?o ?l))
(over all (at ?r ?l))
(at start (gripper_is_free ?g))
)
:effect (and (at end (holding ?g ?o))
(at start (not (on ?o ?l)))
(at start (not (gripper_is_free ?g)))
)
)
; stage an object ?o in a robot platform ?rp which is not occupied with a gripper ?g
; which is holding the object ?o
(:durative-action stage
:parameters (?o - object ?rp - robot_platform ?g - gripper)
:duration (= ?duration 1)
:condition (and (at start (holding ?g ?o))
(at start (not (occupied ?rp)))
(at start (not (gripper_is_free ?g)))
)
:effect (and (at start (not (holding ?g ?o)))
(at start (gripper_is_free ?g))
(at start (stored ?o ?rp))
(at start (occupied ?rp))
)
)
; unstage an object ?o stored on a robot platform ?rp with a free gripper ?g
(:durative-action unstage
:parameters (?o - object ?rp - robot_platform ?g - gripper)
:duration (= ?duration 1)
:condition (and (at start (gripper_is_free ?g))
(at start (stored ?o ?rp))
(at start (not (holding ?g ?o)))
)
:effect (and (at start (not (gripper_is_free ?g)))
(at start (not (stored ?o ?rp)))
(at start (not (occupied ?rp)))
(at start(holding ?g ?o))
)
)
; places and object ?o with a gripper ?g which is holding the object ?o
; with a robot ?r at a location ?l on robot_platform ?rp
(:durative-action drop_on_platform
:parameters (?o - object ?l - location ?g - gripper ?r - robot ?rp - robot_platform)
:duration (= ?duration 1)
:condition (and (over all (at ?r ?l))
(at start (holding ?g ?o))
(at start (not (stored ?o ?rp)))
)
:effect (and (at end (gripper_is_free ?g)) ; the gripper is free
(at end (on ?o ?l)) ; object is now on location l
(at start (not (holding ?g ?o))) ; the gripper is no longer holding the object
)
)
)
Problem:
(define (problem problem_1)
(:domain idmind_agent)
(:objects
dock S1 S2 S3 S4 S5 - location
platform_middle platform_left platform_right - robot_platform
idmind - robot
o1 o2 - object
robotiq - gripper
)
(:init
(at idmind dock)
(on o1 S2)
(on o2 S2)
(not (occupied platform_middle))
(not (occupied platform_left))
(not (occupied platform_right))
(gripper_is_free robotiq)
)
(:goal
(and
(on o1 S1)
(on o2 S4)
)
)
)
But I'm getting this error that I'm not being able to understand. I wonder if you can help me with what I'm missing.
rosrun rosplan_planning_system popf new.domain.pddl new_problem.pddl
Critical Errors Encountered in Domain/Problem File
--------------------------------------------------
Due to critical errors in the supplied domain/problem file, the planner
has to terminate. The errors encountered are as follows:
Errors: 1, warnings: 9
new_problem.pddl: line: 11: Warning: Undeclared requirement :typing
new_problem.pddl: line: 11: Warning: Undeclared requirement :typing
new_problem.pddl: line: 11: Warning: Undeclared requirement :typing
new_problem.pddl: line: 11: Warning: Undeclared requirement :typing
new_problem.pddl: line: 11: Warning: Undeclared requirement :typing
new_problem.pddl: line: 14: Warning: Undeclared symbol: at
new_problem.pddl: line: 15: Warning: Undeclared symbol: on
new_problem.pddl: line: 17: Warning: Undeclared symbol: occupied
new_problem.pddl: line: 20: Warning: Undeclared symbol: gripper_is_free
new_problem.pddl: line: 30: Error: Syntax error in problem file - types used, but no :types section in domain file.
Thank you very much in advance for your help.

PDDL syntax error, ':DURATIVE-ACTIONS' : domain definition expected

I was modeling a domain file with durative actions. I am using the PDDL plugin for VS Code. The code does not have any syntax error problems. The Planner from HTTP://solver.planning.domains/solve return an error
/tmp/solver_planning_domains_tmp_41rdIKx0z0gCb/domain.pddl: syntax error in line 5, ':DURATIVE-ACTIONS': domain definition expected Failed to parse the problem -- list index out of range
The complete domain file big to post here, so the related part of code is:
I appreciated your help.
(define (domain test)
(:requirements :strips :typing :fluents :durative-actions :duration-inequalities :negative-preconditions :equality )
(:types
getbot - robot
wp0 wp1 charging_station object_location - location
a1 a2 a3 - area
bat1 charger - power
gripper
obj- object
)
(:predicates
;General predicates
(robot-at ?rb - robot ?l - location)
(location-situated ?l - location ?a - area) ;location situated in which area
;Gripper related predicates
(object-found ?o - object)
(object-at ?o - object ?obj_loc - location)
(object-placed ?o - object ?obj_loc - location)
(gripper-empty ?rb - robot ?gr - gripper)
(holding-object ?rb - robot ?o - object)
Thank you in advance
The planner on that server doesn't support durative actions.

SPARQL: Dividing a BGP into multiple Groups

In a previous question, a comment suggests that
select ?x ?y where {
{?x rdf:type ex:someType}
{?x ex:someProperty ?y}
}
is like (not identical) to:
select ?x ?y where {
?x rdf:type ex:someType.
?x ex:someProperty ?y.
}
Same triple patterns are used. However, the first query contains two BGPs (each one in a group pattern), while the second contains one BGP (no group patterns).
The algebra for the first query is a JOIN between two BGPs while the algebra of the second is only a BGP.
First query algebra (Apache Jena)
(project (?x ?y)
(join
(bgp (triple ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.example.com/someType>))
(bgp (triple ?x <http://www.example.com/someProperty> ?y))))
Second query algebra (Apache Jena):
(project (?x ?y)
(bgp
(triple ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.example.com/someType>)
(triple ?x <http://www.example.com/someProperty> ?y)
))
In the original question, the answer suggest that they are not identical and argues
If the SPARQL entailment is supported, then the separate {} are evaluated for entailment separately.
if you use labels bnodes in queries there restrictions cross {}
if you add FILTERS, then they do not apply outside the {} they are written in.
its a different abstract syntax tree. All minor points but which may come into play later.
Now let's put the blank nodes (2) and the different syntax trees aside (4), and ask the following: Would the two queries, in any case, yield different results because of filter (3) or entailment(1)? I do not see any possibility for that. Well, those who have a different opinion, may you, please show with some example?
Scope of FILTER is affected.
In:
select ?x ?y where {
{?x rdf:type ex:someType FILTER (?y > 0 ) }
{?x ex:someProperty ?y}
}
The FILTER is false always because ?y is unbound so the expression is error and the FILTER is false regardless of the ?x ex:someProperty ?y.
(3) and (4) are related.

SPARQL Distinct pairs

I've got a table, where there are documents with identical authors. I need to get the distinct pairs of documents. I did the following:
SELECT DISTINCT ?d1 ?d2 WHERE {
?d1 myns:creator ?x.
?d2 myns:creator ?y.
FILTER (?x=?y && ?d1!=?d2).
}
GROUP BY ?d1 ?d2
But for this both DOC1, DOC2 and DOC2, DOC1 are in the result. I need to get rid of one of the pairs.
Here is the whole triples database:
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix myns: <http://my.local.namespace#> .
_:doc1 rdf:type myns:Document.
_:doc1 myns:creator _:Pete.
_:doc1 myns:year "2000"^^xsd:integer.
_:doc1 myns:publisher _:p1.
_:doc2 rdf:type myns:Document.
_:doc2 myns:creator _:John.
_:doc2 myns:year "2004"^^xsd:integer.
_:doc2 myns:publisher _:p2.
_:doc3 rdf:type myns:Document.
_:doc3 myns:creator _:Pete.
_:doc3 myns:publisher _:p3.
_:doc4 rdf:type myns:Document.
_:doc4 myns:creator _:Bob.
_:doc4 myns:year "2010"^^xsd:integer.
_:doc4 myns:publisher _:p2.
_:Pete rdf:type myns:Person.
_:Pete myns:knows _:Bob.
_:Pete myns:knows _:John .
_:John rdf:type myns:Person.
_:John myns:age "29"^^xsd:integer.
_:John myns:knows _:Bob.
_:Bob rdf:type myns:Person.
_:Bob myns:age "35"^^xsd:integer.
The result, that I am getting, after executing query is:
D1 D2
_:891f1e98-b411-4e54-9533-18d530f09c6ddoc1 _:891f1e98-b411-4e54-9533-18d530f09c6ddoc3
_:891f1e98-b411-4e54-9533-18d530f09c6ddoc3 _:891f1e98-b411-4e54-9533-18d530f09c6ddoc1
As it is noticeable, technically both pairs are same. I junst need distinct one (i.e. one of them is enough). I am not sure about enviromental characteristics. But there is Sesame framework
This will work in some systems:
SELECT ?d1 ?d2 WHERE {
?d1 myns:creator ?x.
?d2 myns:creator ?y.
FILTER (?x=?y && STR(IRI(?d1)) < STR(IRI(?d2))).
}
?d1 and ?d2 are going to be blank nodes. But blank nodes are blank.
So to provide the ordering for <, we need some kind of query-wide label or value associated with each one.
Your data does not have any distinguishing triples for each person.It would be better to put real names in the data:
_:Pete rdfs:label "Pete" .
Even better, use the FOAF vocabulary.
Some systems allow blank nodes in IRI() - technically it's an extension of the SPARQL specification. You can then take the STR form and compare. that works on your data for me (Apache Jena) - You don't say which RDF system you are using.
The best solution is put distinguishing information into the data.
You can do this with a little trick: turn the != into a < (or >), and convert the values to strings, so you can do lexical comparisons:
SELECT DISTINCT ?d1 ?d2 WHERE {
?d1 myns:creator ?x.
?d2 myns:creator ?y.
FILTER (?x=?y && STR(?d1) < STR(?d2)).
}
GROUP BY ?d1 ?d2
This works on the idea that for any pair of identifiers that are not equal, one identifier is always greater than the other (by lexical ordering). So of any two pairs, only one will actually be selected.
Update so now that you've shown your data, we can see that the problem is that you are not using IRIs to distinguish your documents, but use blank nodes. The above query does not work because according to the SPARQL standard, blank nodes are unordered (so directly comparing via < does not work), and moreover, the STR function is defined to only operate on literals or IRIs, not on blank nodes.
The best solution is to change your data, and make sure that you use proper IRIs, because regardless of whether you can somehow make this query work on this data, the result would be almost useless: blank nodes have no meaning outside their local scope, so the document identifiers that your query returns can not really be reused; for example, you would not be able to do a SPARQL query that gets any properties specifically for the document _:doc1 (although to be fair Sesame has a workaround for this in the API).
A very simple way to change your blank nodes to IRIs, by the way, is to replace all occurrences of _: in your turtle file with myns:.

Inquiry on example of explicit join in the SPARQL

I have following sparql query(from the book, semantic web primer):
select ?n
where
{
?x rdf:type uni:Course;
uni:isTaughtBy :949352
?c uni:name ?n .
FILTER(?c=?x) .
}
In this case, I guess this code is same as the the following:
Select ?n
Where
{
?x rdf:type uni:course;
uni:isTaughtBy :949352 .
?x uni:name ?n .
}
Does this query lead to coding error?
No, I don't see why it should give you an error or produce wrong results. Just make sure to always use the right case (uni:Course vs. uni:course), as SPARQL is case sensitive.
To be honest, the first version seems rather obscure as it uses a FILTER without a real need for it. That said, you may further slim down your query if you wish:
SELECT ?n
WHERE
{
?x rdf:type uni:Course;
uni:isTaughtBy :949352;
uni:name ?n .
}
However, keep in mind that saving characters does not always lead to improved readability.
For your example yes the queries are identical and there would be no value in using a FILTER over a join.
However the reason why you might use the FILTER form is the difference in semantics between joins and the = operator
Joins require that the values of the variables be exactly the same RDF term, whereas = does value equality - do the values of RDF terms that represent the same value? This is primarily a concern when one/both of the values may have literal values
It's easier to see if you take a specific example, assume ?x=4 and ?c = 4.0 (which is a bad example for your query but illustrates the point)
?x = ?c would give true while a join would give no results because they are not the exact same term