def translate_task(strips_to_sas, ranges, translation_key, mutex_key, init, goals, actions, axioms, metric): axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms( actions, axioms, goals) init = init + axiom_init #axioms.sort(key=lambda axiom: axiom.name) #for axiom in axioms: # axiom.dump() init_values = [rang - 1 for rang in ranges] # Closed World Assumption: Initialize to "range - 1" == Nothing. for fact in init: pairs = strips_to_sas.get(fact, []) # empty for static init facts for var, val in pairs: assert init_values[ var] == ranges[var] - 1, "Inconsistent init facts!" init_values[var] = val init = sas_tasks.SASInit(init_values) goal_pairs = list( translate_strips_conditions(goals, strips_to_sas, ranges).items()) goal = sas_tasks.SASGoal(goal_pairs) operators = translate_strips_operators(actions, strips_to_sas, ranges) axioms = translate_strips_axioms(axioms, strips_to_sas, ranges) axiom_layers = [-1] * len(ranges) for atom, layer in axiom_layer_dict.items(): assert layer >= 0 [(var, val)] = strips_to_sas[atom] axiom_layers[var] = layer variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key) mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key] return sas_tasks.SASTask(variables, mutexes, init, goal, operators, axioms, metric)
def translate_task(strips_to_sas, ranges, translation_key, mutex_dict, mutex_ranges, mutex_key, init, goals, actions, axioms, metric, implied_facts): with timers.timing("Processing axioms", block=True): axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms( actions, axioms, goals) init = init + axiom_init #axioms.sort(key=lambda axiom: axiom.name) #for axiom in axioms: # axiom.dump() if DUMP_TASK: # Remove init facts that don't occur in strips_to_sas: they're constant. nonconstant_init = filter(strips_to_sas.get, init) dump_task(nonconstant_init, goals, actions, axioms, axiom_layer_dict) init_values = [rang - 1 for rang in ranges] # Closed World Assumption: Initialize to "range - 1" == Nothing. for fact in init: pairs = strips_to_sas.get(fact, []) # empty for static init facts for var, val in pairs: curr_val = init_values[var] if curr_val != ranges[var] - 1 and curr_val != val: assert False, "Inconsistent init facts! [fact = %s]" % fact init_values[var] = val init = sas_tasks.SASInit(init_values) goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges, mutex_dict, mutex_ranges) if goal_dict_list is None: # "None" is a signal that the goal is unreachable because it # violates a mutex. return unsolvable_sas_task("Goal violates a mutex") #assert len(goal_dict_list) == 1, "Negative goal not supported" ## we could substitute the negative goal literal in ## normalize.substitute_complicated_goal, using an axiom. We currently ## don't do this, because we don't run into this assertion, if the ## negative goal is part of finite domain variable with only two ## values, which is most of the time the case, and hence refrain from ## introducing axioms (that are not supported by all heuristics) goal_pairs = list(goal_dict_list[0].items()) goal = sas_tasks.SASGoal(goal_pairs) operators = translate_strips_operators(actions, strips_to_sas, ranges, mutex_dict, mutex_ranges, implied_facts) axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, mutex_dict, mutex_ranges) axiom_layers = [-1] * len(ranges) for atom, layer in axiom_layer_dict.items(): assert layer >= 0 [(var, val)] = strips_to_sas[atom] axiom_layers[var] = layer variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key) mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key] return sas_tasks.SASTask(variables, mutexes, init, goal, operators, axioms, metric)
def translate_task(strips_to_sas, ranges, translation_key, mutex_dict, mutex_ranges, mutex_key, init, init_unknown, init_oneof, init_formula, goals, actions, observation_actions, axioms, metric, implied_facts): with timers.timing("Processing axioms", block=True): axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms( actions, axioms, goals) init = init + axiom_init #axioms.sort(key=lambda axiom: axiom.name) #for axiom in axioms: # axiom.dump() if DUMP_TASK: # Remove init facts that don't occur in strips_to_sas: they're constant. nonconstant_init = filter(strips_to_sas.get, init) dump_task(nonconstant_init, goals, actions, axioms, axiom_layer_dict) # Closed World Assumption false_facts = list(range(len(ranges))) for fact in init_unknown: pairs = strips_to_sas.get(fact, []) for pair in pairs: false_facts.remove(pair[0]) facts = [] for fact in init: assert fact not in init_unknown pairs = strips_to_sas.get(fact, []) for pair in pairs: false_facts.remove(pair[0]) if pairs: facts = facts + pairs for var in false_facts: assert fact not in init_unknown facts.append((var, ranges[var] - 1)) facts_oneof = [] for oneof in init_oneof: assert len(oneof) >= 2 for fact in oneof: assert fact in init_unknown l = [] for one in oneof: l = l + strips_to_sas.get(one, []) facts_oneof.append(l) # move to conditions.py? def translate_formula(formula, result, strips_to_sas, ranges, mutex_dict, mutex_ranges): if isinstance(formula, pddl.conditions.Atom): assert formula in init_unknown result.append(strips_to_sas.get(formula, [])) elif isinstance(formula, pddl.conditions.NegatedAtom): dict_list = translate_strips_conditions([formula], strips_to_sas, ranges, mutex_dict, mutex_ranges) assert len(dict_list) == 1 result.append(dict_list[0].items()) elif isinstance(formula, pddl.conditions.Disjunction): result.append("or(") for part in formula.parts: translate_formula(part, result, strips_to_sas, ranges, mutex_dict, mutex_ranges) result.append(")") elif isinstance(formula, pddl.conditions.Conjunction): result.append("and(") for part in formula.parts: translate_formula(part, result, strips_to_sas, ranges, mutex_dict, mutex_ranges) result.append(")") else: assert False, print(formula) formulae = [] for formula in init_formula: result = [] translate_formula(formula, result, strips_to_sas, ranges, mutex_dict, mutex_ranges) formulae.append(result) init = sas_tasks.SASInit(facts, facts_oneof, formulae) goal_dict_list = translate_strips_conditions(goals, strips_to_sas, ranges, mutex_dict, mutex_ranges) if goal_dict_list is None: # "None" is a signal that the goal is unreachable because it # violates a mutex. return unsolvable_sas_task("Goal violates a mutex") assert len(goal_dict_list) == 1, "Negative goal not supported" ## we could substitute the negative goal literal in ## normalize.substitute_complicated_goal, using an axiom. We currently ## don't do this, because we don't run into this assertion, if the ## negative goal is part of finite domain variable with only two ## values, which is most of the time the case, and hence refrain from ## introducing axioms (that are not supported by all heuristics) goal_pairs = list(goal_dict_list[0].items()) goal = sas_tasks.SASGoal(goal_pairs) operators = translate_strips_operators(actions, strips_to_sas, ranges, mutex_dict, mutex_ranges, implied_facts) observation_operators = translate_strips_operators(observation_actions, strips_to_sas, ranges, mutex_dict, mutex_ranges, implied_facts) axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, mutex_dict, mutex_ranges) axiom_layers = [-1] * len(ranges) for atom, layer in axiom_layer_dict.items(): assert layer >= 0 [(var, val)] = strips_to_sas[atom] axiom_layers[var] = layer variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key) mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key] return sas_tasks.SASTask(variables, mutexes, init, goal, operators + observation_operators, axioms, metric)
def translate_task(strips_to_sas, ranges, translation_key, numeric_strips_to_sas, num_count, mutex_dict, mutex_ranges, mutex_key, init, num_init, goal_list, global_constraint, actions, axioms, num_axioms, num_axioms_by_layer, num_axiom_map, const_num_axioms, metric, implied_facts, init_constant_predicates, init_constant_numerics): with timers.timing("Processing axioms", block=True): axioms, axiom_init, axiom_layer_dict = axiom_rules.handle_axioms( actions, axioms, goal_list, global_constraint) init = init + axiom_init if options.dump_task: # Remove init facts that don't occur in strips_to_sas: they're constant. nonconstant_init = filter(strips_to_sas.get, init) dump_task(nonconstant_init, goal_list, actions, axioms, axiom_layer_dict) init_values = [rang - 1 for rang in ranges] # Closed World Assumption: Initialize to "range - 1" == Nothing. for fact in init: pairs = strips_to_sas.get(fact, []) # empty for static init facts for var, val in pairs: curr_val = init_values[var] if curr_val != ranges[var] - 1 and curr_val != val: assert False, "Inconsistent init facts! [fact = %s]" % fact init_values[var] = val comparison_axioms = [{}, []] goal_dict_list = translate_strips_conditions(goal_list, strips_to_sas, ranges, numeric_strips_to_sas, mutex_dict, mutex_ranges, comparison_axioms) global_constraint_dict_list = translate_strips_conditions( [global_constraint], strips_to_sas, ranges, numeric_strips_to_sas, mutex_dict, mutex_ranges, comparison_axioms) # print("goal_dict_list = %s" % goal_dict_list) # print("comparison_axioms = %s" %comparison_axioms) if goal_dict_list is None: # "None" is a signal that the goal_list is unreachable because it # violates a mutex. return unsolvable_sas_task("Goal violates a mutex") assert len(goal_dict_list) == 1, "Negative goal not supported" ## we could substitute the negative goal literal in ## normalize.substitute_complicated_goal, using an axiom. We currently ## don't do this, because we don't run into this assertion, if the ## negative goal is part of finite domain variable with only two ## values, which is most of the time the case, and hence refrain from ## introducing axioms (that are not supported by all heuristics) goal_pairs = list(goal_dict_list[0].items()) if not goal_pairs: return solvable_sas_task("Empty goal") sas_goal = sas_tasks.SASGoal(goal_pairs) assert len( global_constraint_dict_list ) == 1 # the key is the axiom fluent, the value (0) the evaluation to true num_init_values = [0.0 ] * num_count # initialize numeric varialbes with 0.0 # if DEBUG: # print("Strips-to-sas dict is") # for entry in strips_to_sas: # print("%s -> %s"%(entry, strips_to_sas[entry])) # print("Numeric Strips-to-sas dict is") # for entry in numeric_strips_to_sas: # print("%s -> %s"%(entry,numeric_strips_to_sas[entry])) relevant_numeric = [] for fact in num_init: var = numeric_strips_to_sas.get(fact.fluent, -1) if var > -1: val = fact.expression.value num_init_values[var] = val if fact.fluent.ntype == 'R': # the corresponding numeric variable is "regular" and therefore relevant relevant_numeric.append(var) operators = translate_strips_operators(actions, strips_to_sas, ranges, numeric_strips_to_sas, mutex_dict, mutex_ranges, implied_facts, comparison_axioms, num_init_values, relevant_numeric) axioms = translate_strips_axioms(axioms, strips_to_sas, ranges, numeric_strips_to_sas, mutex_dict, mutex_ranges, comparison_axioms) sas_num_axioms = [ translate_numeric_axiom(axiom, strips_to_sas, numeric_strips_to_sas) for axiom in num_axioms if axiom not in const_num_axioms and axiom.effect not in num_axiom_map ] axiom_layers = [-1] * len(ranges) # default axiom layer is -1 ## each numeric axiom gets its own layer (a wish of a colleague for ## knowledge compilation or search. If you use only the translator, ## you can change this) num_axiom_layers = [-1] * num_count num_axiom_layer = 0 for layer in num_axioms_by_layer: num_axioms_by_layer[layer].sort(lambda x, y: cmp(x.name, y.name)) for axiom in num_axioms_by_layer[layer]: if axiom.effect not in num_axiom_map: var = numeric_strips_to_sas[axiom.effect] if layer == -1: num_axiom_layers[var] = -1 else: num_axiom_layers[var] = num_axiom_layer num_axiom_layer += 1 # print("comparison_axioms = %s" %comparison_axioms) comp_axiom_init = [2] * len( comparison_axioms[1] ) # initializing comparison axioms with value 3 (none of those) init_values.extend(comp_axiom_init) # for axiom in comparison_axioms[1]: axiom_layers[axiom.effect] = num_axiom_layer for atom, layer in axiom_layer_dict.iteritems(): assert layer >= 0 [(var, val)] = strips_to_sas[atom] axiom_layers[var] = layer + num_axiom_layer + 1 add_key_to_comp_axioms(comparison_axioms, translation_key) variables = sas_tasks.SASVariables(ranges, axiom_layers, translation_key, num_axiom_layer) num_variables = [-1] * num_count num_var_types = ['U'] * num_count # variable type is unknown for entry in numeric_strips_to_sas: num_variables[numeric_strips_to_sas[entry]] = entry num_var_types[numeric_strips_to_sas[entry]] = entry.ntype assert num_count == len(num_variables), "%d nc <-> variables %d" % ( num_count, len(num_variables)) numeric_variables = sas_tasks.SASNumericVariables(num_variables, num_axiom_layers, num_var_types) mutexes = [sas_tasks.SASMutexGroup(group) for group in mutex_key] for axiom in const_num_axioms: # print("Axiom = %s" % axiom) # print("Axiom.effect = %s" % axiom.effect) # print("corresponding variable = %s" % numeric_strips_to_sas.get(axiom.effect)) var = numeric_strips_to_sas.get(axiom.effect) val = axiom.parts[0].value num_init_values[var] = val sas_init = sas_tasks.SASInit(init_values, num_init_values) # print("SASInit is") # sas_init.dump() # look up metric fluent if metric[1] == -1: # minimize unit cost, no metric fluent specified assert metric[0] == '<' sas_metric = metric else: assert metric[ 1] in numeric_strips_to_sas, "Metric fluent %s missing in strips_to_sas_dict" % metric[ 1] # look up (possibly derived) metric fluent to be optimized sas_metric = (metric[0], numeric_strips_to_sas[metric[1]]) # print ("debug check metric: metric=") # print (metric) # print ("sas_metric fluent %d" % sas_metric[1]) # print ("Returning task with global constraint = ",global_constraint_dict_list[0].items()[0]) return sas_tasks.SASTask(variables, numeric_variables, mutexes, sas_init, sas_goal, operators, axioms, comparison_axioms[1], sas_num_axioms, global_constraint_dict_list[0].items()[0], sas_metric, init_constant_predicates, init_constant_numerics)