Skip to content

Commit 821fb14

Browse files
keep generation with disjunctive preconds, add a flag to control it, fix tests
1 parent cb15641 commit 821fb14

File tree

6 files changed

+111
-55
lines changed

6 files changed

+111
-55
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ ENV DEBIAN_FRONTEND=noninteractive
2828
ENV LC_ALL=C.UTF-8
2929
ENV LANG=C.UTF-8
3030

31-
CMD ["fond4ltlf"]
31+
CMD ["fond4ltlf"]

fond4ltlf/__main__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@
5353
help="Path to PDDL file to store the new problem.",
5454
type=click.Path(dir_okay=False),
5555
)
56-
def main(in_domain, in_problem, goal, out_domain, out_problem):
56+
@click.option("--no-disj-preconds", "-n", is_flag=True, default=False, help="No disjunctive preconditions.")
57+
def main(in_domain, in_problem, goal, out_domain, out_problem, no_disj_preconds):
5758
"""From FOND Planning for LTLf/PLTLf Goals to Classical FOND Planning."""
5859
try:
5960
with open(in_domain, "r") as d:
@@ -63,7 +64,7 @@ def main(in_domain, in_problem, goal, out_domain, out_problem):
6364
except Exception:
6465
raise IOError("[ERROR]: Something wrong occurred while parsing the domain and problem.")
6566

66-
domain_prime, problem_prime = execute(pddl_domain, pddl_problem, goal)
67+
domain_prime, problem_prime = execute(pddl_domain, pddl_problem, goal, no_disj_preconds)
6768

6869
try:
6970
with open(out_domain, "w+") as dom:

fond4ltlf/automa/automaton.py

+36-12
Original file line numberDiff line numberDiff line change
@@ -95,43 +95,67 @@ def __str__(self):
9595
automa += "transitions: {}".format(str(self.transitions))
9696
return automa
9797

98-
def create_operators_trans(self, domain_predicates, grounded_symbols):
98+
def create_operators_trans(self, domain_predicates, grounded_symbols, no_disjunctive_preconditions=False):
9999
"""Create operators corresponding to the automaton."""
100100
new_operators = []
101101
my_predicates = [symbol.name for symbol in grounded_symbols]
102102
(parameters, obj_mapping) = self.compute_parameters(domain_predicates, grounded_symbols)
103103
vars_mapping = self.compute_varsMapping(grounded_symbols, obj_mapping)
104104
my_variables = [param.name for param in parameters]
105105
counter = 0
106+
106107
for destination, source_action in self.trans_by_dest.items():
107108
if source_action:
108109
fluents_list_precond = self.compute_preconditions(
109110
source_action, vars_mapping, my_predicates, my_variables
110111
)
111-
if isinstance(fluents_list_precond, FormulaAnd):
112-
new_preconditions = [fluents_list_precond]
113-
else:
114-
# this should be an Or
115-
assert isinstance(fluents_list_precond, FormulaOr)
116-
# for each disjunct, we create a new precondition
112+
113+
if no_disjunctive_preconditions:
114+
# Non-disjunctive mode
115+
assert isinstance(
116+
fluents_list_precond, FormulaOr
117+
), "Expected FormulaOr for disjunctive preconditions"
118+
119+
# For each disjunct, create a new precondition
117120
new_preconditions = [
118121
FormulaAnd(pre.andList + [Literal.negative(Predicate("turnDomain"))])
119122
if isinstance(pre, FormulaAnd)
120123
else FormulaAnd([pre] + [Literal.negative(Predicate("turnDomain"))])
121124
for pre in fluents_list_precond.orList
122125
]
123-
subcounter = 0
124-
for newpre in new_preconditions:
126+
127+
subcounter = 0
128+
for newpre in new_preconditions:
129+
new_effects = self.compute_effects(destination, my_variables)
130+
new_operators.append(
131+
Action(
132+
f"trans-{counter}{subcounter}",
133+
parameters,
134+
newpre,
135+
new_effects,
136+
)
137+
)
138+
subcounter += 1
139+
140+
else:
141+
# Disjunctive mode
142+
if isinstance(fluents_list_precond, FormulaAnd):
143+
new_precondition = fluents_list_precond
144+
else:
145+
new_precondition = FormulaAnd(
146+
[fluents_list_precond] + [Literal.negative(Predicate("turnDomain"))]
147+
)
148+
125149
new_effects = self.compute_effects(destination, my_variables)
126150
new_operators.append(
127151
Action(
128-
"trans-" + str(counter) + str(subcounter),
152+
f"trans-{counter}",
129153
parameters,
130-
newpre,
154+
new_precondition,
131155
new_effects,
132156
)
133157
)
134-
subcounter += 1
158+
135159
counter += 1
136160
else:
137161
pass

fond4ltlf/core.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# You should have received a copy of the GNU General Public License
1717
# along with FOND4LTLf. If not, see <https://www.gnu.org/licenses/>.
1818
#
19-
"""Core module of the fonod4ltlfpltlf tool."""
19+
"""Core module of the fond4ltlf tool."""
2020

2121
import re
2222

@@ -55,7 +55,7 @@ def check_symbols(symbols, parsed_domain):
5555
return True
5656

5757

58-
def execute(planning_domain, planning_problem, goal_formula):
58+
def execute(planning_domain, planning_problem, goal_formula, no_disj_preconds):
5959
"""Execute the compilation."""
6060
pddl_parser = PDDLParser()
6161
parsed_domain = pddl_parser(planning_domain)
@@ -84,7 +84,9 @@ def execute(planning_domain, planning_problem, goal_formula):
8484

8585
mona_output = formula.to_dfa(mona_dfa_out=True)
8686
dfa = parse_dfa(mona_output)
87-
operators_trans, parameters = dfa.create_operators_trans(parsed_domain.predicates, symbols)
87+
operators_trans, parameters = dfa.create_operators_trans(
88+
parsed_domain.predicates, symbols, no_disjunctive_preconditions=no_disj_preconds
89+
)
8890

8991
new_domain = parsed_domain.get_new_domain(parameters, dfa.states, operators_trans)
9092
new_problem = parsed_problem.get_new_problem(list(dfa.accepting_states), symbols)

tests/test_automaton.py

+65-36
Original file line numberDiff line numberDiff line change
@@ -158,29 +158,17 @@ def test_automaton_create_trans_op(self):
158158
).read()
159159
)
160160
grounded_symbols = [Symbol("vehicleat", ["l31"])]
161-
actual_trans_ops, actual_params = self.aut_obj.create_operators_trans(pddl_domain.predicates, grounded_symbols)
161+
actual_trans_ops, actual_params = self.aut_obj.create_operators_trans(
162+
pddl_domain.predicates, grounded_symbols, no_disjunctive_preconditions=True
163+
)
162164
expected_trans_ops = [
163165
Action(
164-
name="trans-0",
166+
name="trans-00",
165167
parameters=[Term.variable("?loc-00", "location")],
166168
preconditions=FormulaAnd(
167169
[
168-
FormulaOr(
169-
[
170-
FormulaAnd(
171-
[
172-
Literal.positive(Predicate("q1", ["?loc-00"])),
173-
Literal.negative(Predicate("vehicleat", ["?loc-00"])),
174-
]
175-
),
176-
FormulaAnd(
177-
[
178-
Literal.positive(Predicate("q2", ["?loc-00"])),
179-
Literal.negative(Predicate("vehicleat", ["?loc-00"])),
180-
]
181-
),
182-
]
183-
),
170+
Literal.positive(Predicate("q1", ["?loc-00"])),
171+
Literal.negative(Predicate("vehicleat", ["?loc-00"])),
184172
Literal.negative(Predicate("turnDomain")),
185173
]
186174
),
@@ -194,27 +182,68 @@ def test_automaton_create_trans_op(self):
194182
),
195183
),
196184
Action(
197-
name="trans-1",
185+
name="trans-01",
198186
parameters=[Term.variable("?loc-00", "location")],
199187
preconditions=FormulaAnd(
200188
[
201-
FormulaOr(
202-
[
203-
FormulaAnd(
204-
[
205-
Literal.positive(Predicate("q1", ["?loc-00"])),
206-
Literal.positive(Predicate("vehicleat", ["?loc-00"])),
207-
]
208-
),
209-
FormulaAnd(
210-
[
211-
Literal.positive(Predicate("q2", ["?loc-00"])),
212-
Literal.positive(Predicate("vehicleat", ["?loc-00"])),
213-
]
214-
),
215-
Literal.positive(Predicate("q3", ["?loc-00"])),
216-
]
217-
),
189+
Literal.positive(Predicate("q2", ["?loc-00"])),
190+
Literal.negative(Predicate("vehicleat", ["?loc-00"])),
191+
Literal.negative(Predicate("turnDomain")),
192+
]
193+
),
194+
effects=FormulaAnd(
195+
[
196+
Literal.positive(Predicate("q2", ["?loc-00"])),
197+
Literal.negative(Predicate("q1", ["?loc-00"])),
198+
Literal.negative(Predicate("q3", ["?loc-00"])),
199+
Literal.positive(Predicate("turnDomain")),
200+
]
201+
),
202+
),
203+
Action(
204+
name="trans-10",
205+
parameters=[Term.variable("?loc-00", "location")],
206+
preconditions=FormulaAnd(
207+
[
208+
Literal.positive(Predicate("q1", ["?loc-00"])),
209+
Literal.positive(Predicate("vehicleat", ["?loc-00"])),
210+
Literal.negative(Predicate("turnDomain")),
211+
]
212+
),
213+
effects=FormulaAnd(
214+
[
215+
Literal.positive(Predicate("q3", ["?loc-00"])),
216+
Literal.negative(Predicate("q1", ["?loc-00"])),
217+
Literal.negative(Predicate("q2", ["?loc-00"])),
218+
Literal.positive(Predicate("turnDomain")),
219+
]
220+
),
221+
),
222+
Action(
223+
name="trans-11",
224+
parameters=[Term.variable("?loc-00", "location")],
225+
preconditions=FormulaAnd(
226+
[
227+
Literal.positive(Predicate("q2", ["?loc-00"])),
228+
Literal.positive(Predicate("vehicleat", ["?loc-00"])),
229+
Literal.negative(Predicate("turnDomain")),
230+
]
231+
),
232+
effects=FormulaAnd(
233+
[
234+
Literal.positive(Predicate("q3", ["?loc-00"])),
235+
Literal.negative(Predicate("q1", ["?loc-00"])),
236+
Literal.negative(Predicate("q2", ["?loc-00"])),
237+
Literal.positive(Predicate("turnDomain")),
238+
]
239+
),
240+
),
241+
Action(
242+
name="trans-12",
243+
parameters=[Term.variable("?loc-00", "location")],
244+
preconditions=FormulaAnd(
245+
[
246+
Literal.positive(Predicate("q3", ["?loc-00"])),
218247
Literal.negative(Predicate("turnDomain")),
219248
]
220249
),

tests/test_fond4ltlf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# along with FOND4LTLf. If not, see <https://www.gnu.org/licenses/>.
1818
#
1919

20-
"""Test the fonod4ltlfpltlf tool."""
20+
"""Test the fond4ltlf tool."""
2121

2222
import os
2323

0 commit comments

Comments
 (0)