Help with "AttributeError: 'FNode' object has no attribute 'lower'" error #622
Replies: 2 comments
-
Hi @juancarlosgss . So, the main problem with your code is HOW you use the So, after I played around a bit, this is what I got, I left some comments in the code where I made the changes. Let me know how this works for you. I also don't know how well the fix from from unified_planning.shortcuts import *
Mover = UserType('Mover')
# Cells are used in the value_demand fluent, so I guessed Cells
# are also Demands, but you will have to check this yourself
Demand = UserType('Demand')
Cell = UserType('Cell', Demand)
value_demand = Fluent('value_demand', IntType(-1,10), m=Demand)
link = Fluent('link', BoolType(), from_cell=Cell, to_cell=Cell)
mover_at = Fluent('mover_at', BoolType(), mover=Mover, cell=Cell)
loaded_at = Fluent('loaded_at', BoolType(), mover=Mover, cell=Cell)
loaded = Fluent('loaded', BoolType(), mover=Mover)
load = InstantaneousAction('load', mover=Mover, from_cell=Cell, d=Demand)
m = load.parameter('mover')
fc = load.parameter('from_cell')
d = load.parameter('d')
load.add_precondition(mover_at(m, fc))
load.add_precondition(GT(value_demand(d),0))
load.add_precondition(Not(loaded(m)))
load.add_effect(loaded(m), True)
load.add_effect(loaded_at(m, fc), True)
load.add_decrease_effect(value_demand(d), 1)
haul = InstantaneousAction('haul', mover=Mover, from_cell=Cell, to_cell=Cell)
m = haul.parameter('mover')
fc = haul.parameter('from_cell')
tc = haul.parameter('to_cell')
haul.add_precondition(loaded(m))
haul.add_precondition(loaded_at(m, fc))
haul.add_precondition(mover_at(m, fc))
haul.add_precondition(link(fc, tc))
haul.add_effect(mover_at(m, fc), False)
haul.add_effect(mover_at(m, tc), True)
dump = InstantaneousAction('dump', mover=Mover, dump_cell=Cell)
m = dump.parameter('mover')
dc = dump.parameter('dump_cell')
dump.add_precondition(loaded(m))
dump.add_precondition(mover_at(m, dc))
dump.add_effect(loaded(m), False)
dump.add_effect(loaded_at(m, dc), False)
dump.add_increase_effect(value_demand(dc), 1)
move = InstantaneousAction('move', mover=Mover, from_cell=Cell, to_cell=Cell, d=Demand)
m = move.parameter('mover')
fc = move.parameter('from_cell')
tc = move.parameter('to_cell')
d = load.parameter('d')
move.add_precondition(Equals(value_demand(d), 0))
move.add_precondition(Not(loaded(m)))
move.add_precondition(Not(loaded_at(m, fc)))
move.add_precondition(mover_at(m, fc))
move.add_precondition(link(fc, tc))
move.add_effect(mover_at(m, fc), False)
move.add_effect(mover_at(m, tc), True)
p1 = Problem('p1')
mover = Object('mover', Mover)
cell1 = Object('cell1', Cell)
cell2 = Object('cell2', Cell)
cell3 = Object('cell3', Cell)
d1 = Object('d1', Demand)
d2 = Object('d2', Demand)
d3 = Object('d3', Demand)
p1.add_object(mover)
p1.add_object(cell1)
p1.add_object(cell2)
p1.add_object(cell3)
p1.add_object(d1)
p1.add_object(d2)
p1.add_object(d3)
p1.add_action(load)
p1.add_action(haul)
p1.add_action(dump)
p1.add_action(move)
# All the add_fluent methods don't have a fluent call, but just a fluent
# BAD EXAMPLE --> p1.add_fluent(loaded_at(mover, cell2), default_initial_value=False)
# ALSO, you don't need to specify the type here, you already specify it above.
# Specifying the fluent name and type and in the add_fluent method is a way to both create the fluent and add the fluent in the same line.
# examples:
# value_demand = Fluent('value_demand', IntType(-1,10), m=Demand)
# p1.add_fluent(value_demand, default_initial_value=-1)
# vs
# value_demand = p1.add_fluent('value_demand', IntType(-1,10), m=Demand, default_initial_value=-1)
# You could do the same thing with objects
p1.add_fluent(value_demand, default_initial_value=-1)
p1.add_fluent(loaded, default_initial_value=False)
p1.add_fluent(mover_at, default_initial_value=False)
p1.add_fluent(loaded_at, default_initial_value=False)
p1.add_fluent(link, default_initial_value=True)
p1.set_initial_value(loaded(mover), False)
p1.set_initial_value(mover_at(mover, cell3), True)
p1.set_initial_value(link(cell2, cell1), True)
p1.set_initial_value(link(cell2, cell3), True)
p1.set_initial_value(link(cell3, cell2), True)
p1.set_initial_value(value_demand(d1), -1)
p1.set_initial_value(value_demand(d2), 0)
p1.set_initial_value(value_demand(d3), 1)
p1.add_goal(And(Equals(value_demand(d1), -1), Equals(value_demand(d2), 0), Equals(value_demand(d3), 0)))
with OneshotPlanner(name='enhsp') as planner:
result = planner.solve(p1)
plan = result.plan
if plan is not None:
print("%s returned:" % planner.name)
print(plan)
else:
print("No plan found.") |
Beta Was this translation helpful? Give feedback.
-
hi @Framba-Luca, Thank you for pointing out the issue with the use of Problem.add_fluent. Your explanation helped me identify the errors in how I was handling fluents, and I’ve managed to get the code working correctly now. The fix regarding the transition from Demands to Cells also provided some clarity, and although I’m still refining how this change impacts the overall problem, it’s definitely been helpful. I appreciate your input and the time you took to make those changes. Thanks again for your help! |
Beta Was this translation helpful? Give feedback.
-
Hi everyone,
I'm working on a project using Python and I've encountered an error that I can't figure out how to fix. The error I'm receiving is:
AttributeError: 'FNode' object has no attribute 'lower'
this error occurs when I try to generate the plan. The code is the following
`!apt-get install openjdk-17-jdk
%pip install unified-planning[enhsp]
from unified_planning.shortcuts import *
Mover = UserType('Mover')
Cell = UserType('Cell')
Demand = UserType('Demand')
value_demand = Fluent('value_demand', IntType(-1,10), m=Demand)
link = Fluent('link', BoolType(), from_cell=Cell, to_cell=Cell)
mover_at = Fluent('mover_at', BoolType(), mover=Mover, cell=Cell)
loaded_at = Fluent('loaded_at', BoolType(), mover=Mover, cell=Cell)
loaded = Fluent('loaded', BoolType(), mover=Mover)
load = InstantaneousAction('load', mover=Mover, from_cell=Cell, d=Demand)
m = load.parameter('mover')
fc = load.parameter('from_cell')
d = load.parameter('d')
load.add_precondition(mover_at(m, fc))
load.add_precondition(GT(value_demand(d),0))
load.add_precondition(Not(loaded(m)))
load.add_effect(loaded(m), True)
load.add_effect(loaded_at(m, fc), True)
load.add_decrease_effect(value_demand(d), 1)
haul = InstantaneousAction('haul', mover=Mover, from_cell=Cell, to_cell=Cell)
m = haul.parameter('mover')
fc = haul.parameter('from_cell')
tc = haul.parameter('to_cell')
haul.add_precondition(loaded(m))
haul.add_precondition(loaded_at(m, fc))
haul.add_precondition(mover_at(m, fc))
haul.add_precondition(link(fc, tc))
haul.add_effect(mover_at(m, fc), False)
haul.add_effect(mover_at(m, tc), True)
dump = InstantaneousAction('dump', mover=Mover, dump_cell=Cell)
m = dump.parameter('mover')
dc = dump.parameter('dump_cell')
dump.add_precondition(loaded(m))
dump.add_precondition(mover_at(m, dc))
dump.add_effect(loaded(m), False)
dump.add_effect(loaded_at(m, dc), False)
dump.add_increase_effect(value_demand(dc), 1)
move = InstantaneousAction('move', mover=Mover, from_cell=Cell, to_cell=Cell, d=Demand)
m = move.parameter('mover')
fc = move.parameter('from_cell')
tc = move.parameter('to_cell')
d = load.parameter('d')
move.add_precondition(Equals(value_demand(d), 0))
move.add_precondition(Not(loaded(m)))
move.add_precondition(Not(loaded_at(m, fc)))
move.add_precondition(mover_at(m, fc))
move.add_precondition(link(fc, tc))
move.add_effect(mover_at(m, fc), False)
move.add_effect(mover_at(m, tc), True)
p1 = Problem('p1')
mover = Object('mover', Mover)
cell1 = Object('cell1', Cell)
cell2 = Object('cell2', Cell)
cell3 = Object('cell3', Cell)
#from_cell = Object('from_cell', Cell)
#to_cell = Object('to_cell', Cell)
#dump_cell = Object('dump_cell', Cell)
d1 = Object('d1', Demand)
d2 = Object('d2', Demand)
d3 = Object('d3', Demand)
p1.add_object(mover)
p1.add_object(cell1)
p1.add_object(cell2)
p1.add_object(cell3)
p1.add_object(d1)
p1.add_object(d2)
p1.add_object(d3)
p1.add_action(load)
p1.add_action(haul)
p1.add_action(dump)
p1.add_action(move)
p1.add_fluent(value_demand(d1), IntType(), default_initial_value=-1)
p1.add_fluent(value_demand(d2), IntType(), default_initial_value=0)
p1.add_fluent(value_demand(d3), IntType(), default_initial_value=1)
p1.add_fluent(loaded(mover), default_initial_value=False)
p1.add_fluent(mover_at, default_initial_value=False)
#p1.add_fluent(Mover_at(mover, cell2), default_initial_value=False)
#p1.add_fluent(Mover_at(mover, cell3), default_initial_value=False)
p1.add_fluent(loaded_at, default_initial_value=False)
#p1.add_fluent(Loaded_at(mover, cell2), default_initial_value=False)
#p1.add_fluent(Loaded_at(mover, cell3), default_initial_value=False)
p1.add_fluent(link(cell2, cell1), default_initial_value=True)
p1.add_fluent(link(cell2, cell3), default_initial_value=True)
p1.add_fluent(link(cell3, cell2), default_initial_value=True)
p1.set_initial_value(loaded(mover), False)
p1.set_initial_value(mover_at(mover, cell3), True)
p1.set_initial_value(link(cell2, cell1), True)
p1.set_initial_value(link(cell2, cell3), True)
p1.set_initial_value(link(cell3, cell2), True)
p1.set_initial_value(value_demand(d1), -1)
p1.set_initial_value(value_demand(d2), 0)
p1.set_initial_value(value_demand(d3), 1)
p1.add_goal(And(Equals(value_demand(d1), -1), Equals(value_demand(d2), 0), Equals(value_demand(d3), 0)))
p1
with OneshotPlanner(name='enhsp') as planner:
result = planner.solve(p1)
plan = result.plan
if plan is not None:
print("%s returned:" % planner.name)
print(plan)
else:
print("No plan found.")`
I would greatly appreciate it if someone could help me identify the cause of this error and how to fix it. I've tried several things but haven't had any success so far.
Thanks in advance for your help!
Best regards,
Beta Was this translation helpful? Give feedback.
All reactions