actions.py
Go to the documentation of this file.
00001 # -*- coding: latin-1 -*-
00002 
00003 import copy
00004 
00005 import conditions
00006 import effects
00007 import f_expression
00008 import pddl_types
00009 
00010 class Action(object):
00011     def __init__(self, name, parameters, precondition, effects):
00012         self.name = name
00013         self.parameters = parameters
00014         self.condition = precondition
00015         self.effects = effects
00016         self.uniquify_variables()
00017     def parse(alist):
00018         iterator = iter(alist)
00019         assert iterator.next() == ":action"
00020         name = iterator.next()
00021         parameters_tag_opt = iterator.next()
00022         if parameters_tag_opt == ":parameters":
00023             parameters = pddl_types.parse_typed_list(iterator.next(),
00024                                                      only_variables=True)
00025             precondition_tag_opt = iterator.next()
00026         else:
00027             parameters = []
00028             precondition_tag_opt = parameters_tag_opt
00029         if precondition_tag_opt == ":precondition":
00030             precondition = conditions.parse_condition(iterator.next())
00031             effect_tag = iterator.next()
00032         else:
00033             precondition = conditions.Conjunction([])
00034             effect_tag = precondition_tag_opt
00035         assert effect_tag == ":effect"
00036         effect_list = iterator.next()
00037         eff = []
00038         effects.parse_effects(effect_list,eff)
00039         for rest in iterator:
00040             assert False, rest
00041         return Action(name, parameters, precondition, eff)
00042     parse = staticmethod(parse)
00043     def dump(self):
00044         print "%s(%s)" % (self.name, ", ".join(map(str, self.parameters)))
00045         print "Precondition:"
00046         self.condition.dump()
00047         print "Effects:"
00048         for eff in self.effects:
00049             eff.dump()
00050     def uniquify_variables(self):
00051         self.type_map = dict([(par.name, par.type) for par in self.parameters])
00052         self.condition = self.condition.uniquify_variables(self.type_map)
00053         for effect in self.effects:
00054             effect.uniquify_variables(self.type_map)
00055     def relaxed(self):
00056         new_effects = []
00057         for eff in self.effects:
00058             relaxed_eff = eff.relaxed()
00059             if relaxed_eff:
00060                 new_effects.append(relaxed_eff)
00061         return Action(self.name, self.parameters,
00062                       self.condition.relaxed().simplified(),
00063                       new_effects)
00064     def untyped(self):
00065         # We do not actually remove the types from the parameter lists,
00066         # just additionally incorporate them into the conditions.
00067         # Maybe not very nice.
00068         result = copy.copy(self)
00069         parameter_atoms = [par.to_untyped_strips() for par in self.parameters]
00070         new_precondition = self.condition.untyped()
00071         result.condition = conditions.Conjunction(parameter_atoms + [new_precondition])
00072         result.effects = [eff.untyped() for eff in self.effects]
00073         return result
00074 
00075     def instantiate(self, var_mapping, init_facts, fluent_facts, init_function_vals,
00076                     fluent_functions, task, new_axiom, new_modules, objects_by_type):
00077         """Return a PropositionalAction which corresponds to the instantiation of
00078         this action with the arguments in var_mapping. Only fluent parts of the
00079         conditions (those in fluent_facts) are included. init_facts are evaluated
00080         whilte instantiating.
00081         Precondition and effect conditions must be normalized for this to work.
00082         Returns None if var_mapping does not correspond to a valid instantiation
00083         (because it has impossible preconditions or an empty effect list.)"""
00084         arg_list = [var_mapping[conditions.Variable(par.name)].name for par in self.parameters]
00085         name = "(%s %s)" % (self.name, " ".join(arg_list))
00086 
00087         precondition = []
00088         try:
00089             self.condition.instantiate(var_mapping, init_facts, fluent_facts, 
00090                                        init_function_vals, fluent_functions, task,
00091                                        new_axiom, new_modules, precondition)
00092         except conditions.Impossible:
00093             return None
00094         effects = []
00095         for eff in self.effects:
00096             eff.instantiate(var_mapping, init_facts, fluent_facts, 
00097                             init_function_vals, fluent_functions, task, 
00098                             new_axiom, new_modules, objects_by_type, effects)
00099         if effects:
00100             return PropositionalAction(name, precondition, effects)
00101         else:
00102             return None
00103 
00104 class DurativeAction(object):
00105     def __init__(self, name, parameters, duration, conditions, effects):
00106         self.name = name
00107         self.parameters = parameters
00108         self.orig_parameter_length = len(parameters)
00109         self.duration = duration
00110         self.condition = conditions
00111         assert len(effects)==2
00112         self.effects = effects
00113         self.uniquify_variables()
00114     def parse(alist):
00115         iterator = iter(alist)
00116         assert iterator.next() == ":durative-action"
00117         name = iterator.next()
00118         print "Parsing durative-action", name
00119         parameters_tag_opt = iterator.next()
00120         if parameters_tag_opt == ":parameters":
00121             parameters = pddl_types.parse_typed_list(iterator.next(),
00122                                                      only_variables=True)
00123             duration_tag = iterator.next()
00124         else:
00125             parameters = []
00126             duration_tag = parameters_tag_opt
00127         assert duration_tag == ":duration"
00128         duration_list = iterator.next()
00129         if duration_list[0] == "and":
00130             duration_list = duration_list[1:]
00131         else:
00132             duration_list = [duration_list]
00133         duration_start = []
00134         duration_end = []
00135         for item in duration_list: # each item is a simple-duration-constraint
00136             duration = duration_start
00137             if item[0] == "at":
00138                 if item[1] == "end":
00139                     duration = duration_end
00140                 item = item[2]
00141             assert item[0] in ("<=",">=","=")
00142             if len(item) == 3:    # = ?duration 1
00143               assert item[1] == "?duration"
00144               op = item[0]
00145               value = f_expression.parse_expression(item[2])
00146               duration += [(op,value)]
00147             else:                 # should be module: = ?duration [module]
00148               assert item[1] == "?duration"
00149               op = item[0]
00150               mod_list = item[2:]
00151               #print "Modlist:", mod_list
00152               value = conditions.parse_condition(mod_list)
00153               #print "parse to ", value
00154               duration += [(op,value)]
00155               pass
00156         condition_tag = iterator.next()
00157         if condition_tag == ":condition":
00158             condition = conditions.parse_durative_condition(iterator.next())
00159             effect_tag = iterator.next()
00160         else:
00161             condition = conditions.parse_durative_condition([])
00162             effect_tag = condition_tag
00163         assert effect_tag == ":effect"
00164 
00165         effect_list = iterator.next()
00166         effect = [[],[]]
00167         effects.parse_durative_effects(effect_list, effect)
00168         for rest in iterator:
00169             assert False, rest
00170         return DurativeAction(name, parameters, (duration_start,duration_end), condition, effect)
00171     parse = staticmethod(parse)
00172     def dump(self):
00173         if self.orig_parameter_length != len(self.parameters):
00174             print "%s(%s, (%s))" % (self.name, 
00175                               ", ".join(map(str, self.parameters[0:self.orig_parameter_length])), 
00176                               ", ".join(map(str, self.parameters[self.orig_parameter_length:])))
00177         else:
00178             print "%s(%s)" % (self.name, ", ".join(map(str, self.parameters)))
00179         if len(self.duration[0]) > 0:
00180             print "duration (values from start):"
00181             for (op, val) in self.duration[0]:
00182                 print "  " + op
00183                 val.dump("    ")
00184         if len(self.duration[1]) > 0:
00185             print "duration (values from end):"
00186             for (op, val) in self.duration[1]:
00187                 print "  " + op
00188                 val.dump("    ")
00189         print "start condition:"
00190         self.condition[0].dump()
00191         print "over all condition:"
00192         self.condition[1].dump()
00193         print "end condition:"
00194         self.condition[2].dump()
00195         print "start effects:"
00196         for eff in self.effects[0]:
00197             eff.dump()
00198         print "end effects:"
00199         for eff in self.effects[1]:
00200             eff.dump()
00201     def __str__(self):
00202         return "<Action %s>" % self.name
00203     def uniquify_variables(self):
00204         self.type_map = dict([(par.name, par.type) for par in self.parameters])
00205         for index, condition in enumerate(self.condition):
00206             self.condition[index] = condition.uniquify_variables(self.type_map)
00207         for effects in self.effects:
00208             for effect in effects:
00209                 effect.uniquify_variables(self.type_map)
00210     def instantiate(self, var_mapping, init_facts, fluent_facts, init_function_vals,
00211                     fluent_functions, task, new_axiom, new_modules, objects_by_type):
00212         """Return a PropositionalDurativeAction which corresponds to the instantiation of
00213         this action with the arguments in var_mapping. Only fluent parts of the
00214         conditions (those in fluent_facts) are included. init_facts are evaluated
00215         whilte instantiating.
00216         Precondition and effect conditions must be normalized for this to work.
00217         Returns None if var_mapping does not correspond to a valid instantiation
00218         (because it has impossible preconditions or an empty effect list.)"""
00219 
00220         arg_list = [var_mapping[conditions.Variable(par.name)].name for par in self.parameters]
00221         name = "(%s %s)" % (self.name, " ".join(arg_list[:self.orig_parameter_length]))
00222 
00223         try:
00224             inst_duration = [[],[]]
00225             for dura in (0, 1):
00226               for (op, pne) in self.duration[dura]:
00227                 if isinstance(pne, conditions.ModuleCall):
00228                   result = []
00229                   pne.instantiate(var_mapping, init_facts, fluent_facts,
00230                       init_function_vals, fluent_functions, task, new_axiom, new_modules, result)
00231                   assert len(result) == 1, "Something when wrong when instantiating cost module"
00232                   inst_duration[dura].append((op, result[0]))
00233                 else:
00234                   inst_duration[dura].append((op,pne.instantiate(var_mapping, fluent_functions, 
00235                       init_function_vals, task, new_axiom)))
00236         except ValueError, e:
00237             print "dropped action %s" % name
00238             print "Error: %s" % e
00239             return None
00240         
00241         inst_conditions = [[],[],[]]
00242         for time,condition in enumerate(self.condition):
00243             try:
00244                 condition.instantiate(var_mapping, init_facts, fluent_facts, 
00245                                       init_function_vals, fluent_functions, task,
00246                                       new_axiom, new_modules, inst_conditions[time])
00247             except conditions.Impossible:
00248                 return None
00249         effects = [[],[]]
00250         for time,timed_effects in enumerate(self.effects):
00251             for eff in timed_effects:
00252                 eff.instantiate(var_mapping, init_facts, fluent_facts, 
00253                                 init_function_vals, fluent_functions, task, 
00254                                 new_axiom, new_modules, objects_by_type, effects[time])
00255         if effects:
00256             return PropositionalDurativeAction(name, inst_duration, inst_conditions, effects)
00257         else:
00258             return None
00259 #    def relaxed(self):
00260 #        new_effects = []
00261 #        for eff in self.effects:
00262 #            relaxed_eff = eff.relaxed()
00263 #            if relaxed_eff:
00264 #                new_effects.append(relaxed_eff)
00265 #        return Action(self.name, self.parameters,
00266 #                      self.condition.relaxed().simplified(),
00267 #                      new_effects)
00268 #    def untyped(self):
00269 #        # We do not actually remove the types from the parameter lists,
00270 #        # just additionally incorporate them into the conditions.
00271 #        # Maybe not very nice.
00272 #        result = copy.copy(self)
00273 #        parameter_atoms = [par.to_untyped_strips() for par in self.parameters]
00274 #        new_precondition = self.condition.untyped()
00275 #        result.condition = conditions.Conjunction(parameter_atoms + [new_precondition])
00276 #        result.effects = [eff.untyped() for eff in self.effects]
00277 #        return result
00278 
00279 class PropositionalAction:
00280     def __init__(self, name, precondition, effects):
00281         self.name = name
00282         self.condition = precondition
00283         self.add_effects = []
00284         self.del_effects = []
00285         self.assign_effects = []
00286         for (condition, effect) in effects:
00287             if isinstance(effect,f_expression.FunctionAssignment):
00288                 self.assign_effects.append((condition, effect))
00289             elif effect.negated:
00290                 self.del_effects.append((condition, effect.negate()))
00291             else:
00292                 self.add_effects.append((condition, effect))
00293     def dump(self):
00294         print self.name
00295         for fact in self.condition:
00296             print "PRE: %s" % fact
00297         for cond, fact in self.add_effects:
00298             print "ADD: %s -> %s" % (", ".join(map(str, cond)), fact)
00299         for cond, fact in self.del_effects:
00300             print "DEL: %s -> %s" % (", ".join(map(str, cond)), fact)
00301         for cond, fact in self.assign_effects:
00302             print "ASS: %s -> %s" % (", ".join(map(str, cond)), fact)
00303 
00304 class PropositionalDurativeAction:
00305     def __init__(self, name, duration, conditions, effects):
00306         self.name = name
00307         self.duration = duration
00308         self.conditions = conditions
00309         self.add_effects = [[],[]]
00310         self.del_effects = [[],[]]
00311         self.assign_effects = [[],[]]
00312         for time in range(2):
00313             for (condition, effect) in effects[time]:
00314                 if isinstance(effect,f_expression.FunctionAssignment):
00315                     self.assign_effects[time].append((condition, effect))
00316                 elif effect.negated:
00317                     self.del_effects[time].append((condition, effect.negate()))
00318                 else:
00319                     self.add_effects[time].append((condition, effect))
00320     def dump(self):
00321         print self.name
00322         for duration in self.duration[0]:
00323             print "START DUR: %s %s" % (duration[0],duration[1])
00324         for duration in self.duration[1]:
00325             print "END DUR: %s %s" % (duration[0],duration[1])
00326         for fact in self.conditions[0]:
00327             print "START COND: %s" % fact
00328         for fact in self.conditions[1]:
00329             print "OVER ALL COND: %s" % fact
00330         for fact in self.conditions[2]:
00331             print "END COND: %s" % fact
00332         for cond, fact in self.add_effects[0]:
00333             print "ADD START: %s -> %s" % (", ".join(map(str, cond)), fact)
00334         for cond, fact in self.add_effects[1]:
00335             print "ADD END: %s -> %s" % (", ".join(map(str, cond)), fact)
00336         for cond, fact in self.del_effects[0]:
00337             print "DEL START: %s -> %s" % (", ".join(map(str, cond)), fact)
00338         for cond, fact in self.del_effects[1]:
00339             print "DEL END: %s -> %s" % (", ".join(map(str, cond)), fact)
00340         for cond, fact in self.assign_effects[0]:
00341             print "ASS START: %s -> %s" % (", ".join(map(str, cond)), fact)
00342         for cond, fact in self.assign_effects[1]:
00343             print "ASS END: %s -> %s" % (", ".join(map(str, cond)), fact)


tfd_modules
Author(s): Maintained by Christian Dornhege (see AUTHORS file).
autogenerated on Mon Oct 6 2014 07:52:06