def simultaneous_stream_plan(evaluations, goal_expression, domain, stream_results, negated, unit_costs=False, **kwargs): if negated: raise NotImplementedError(negated) for result in stream_results: if isinstance(result.external, Stream) and result.external.is_fluent(): raise NotImplementedError('Fluents are not supported') applied_streams, deferred_streams = partition_results( evaluations, stream_results, lambda r: False) opt_evaluations = apply_streams(evaluations, applied_streams) stream_domain, stream_result_from_name = add_stream_actions( domain, deferred_streams) if any(map(is_optimizer_result, stream_results)): goal_expression = augment_goal(stream_domain, goal_expression) combined_plan, _ = solve_finite(opt_evaluations, goal_expression, stream_domain, unit_costs=unit_costs, **kwargs) if combined_plan is None: return None, INF stream_plan, action_plan = partition_plan(combined_plan, stream_result_from_name) function_plan = extract_function_plan(opt_evaluations, action_plan, domain, unit_costs) cost = get_plan_cost(opt_evaluations, action_plan, domain, unit_costs) combined_plan = stream_plan + function_plan + action_plan return combined_plan, cost
def locally_optimize(evaluations, store, goal_expression, domain, functions, negative, dynamic_streams, visualize, sampling_time=0): action_plan = store.best_plan if action_plan is None: return None print('\nPostprocessing | Cost: {} | Total Time: {:.3f}'.format(store.best_cost, store.elapsed_time())) # TODO: postprocess current skeletons as well task = task_from_domain_problem(domain, get_problem(evaluations, goal_expression, domain, unit_costs=False)) opt_stream_plan, opt_from_obj = recover_opt_stream_plan(evaluations, action_plan, task) opt_stream_plan += optimistic_process_streams(evaluations_from_stream_plan(evaluations, opt_stream_plan), functions) opt_action_plan = [(name, tuple(opt_from_obj.get(o, o) for o in args)) for name, args in action_plan] pddl_plan = [(name, tuple(map(pddl_from_object, args))) for name, args in opt_action_plan] stream_plan = recover_stream_plan(evaluations, goal_expression, domain, opt_stream_plan, pddl_plan, negative, unit_costs=False) stream_plan = get_synthetic_stream_plan(reorder_stream_plan(stream_plan), dynamic_streams) # TODO: need to make this just streams opt_evaluations = apply_streams(evaluations, stream_plan) opt_cost = get_plan_cost(opt_evaluations, opt_action_plan, domain, unit_costs=False) dump_plans(stream_plan, opt_action_plan, opt_cost) if visualize: log_plans(stream_plan, action_plan, None) create_visualizations(evaluations, stream_plan, None) store.start_time = time.time() store.max_cost = store.best_cost queue = SkeletonQueue(store, evaluations, goal_expression, domain) queue.new_skeleton(stream_plan, opt_action_plan, opt_cost) queue.greedily_process() queue.timed_process(sampling_time)
def simultaneous_stream_plan(evaluations, goal_expression, domain, stream_results, negated, unit_costs=False, **kwargs): # TODO: remove this method in favor of the more general relaxed plan if negated: raise NotImplementedError(negated) for result in stream_results: if isinstance(result.external, Stream) and result.external.is_fluent(): raise NotImplementedError('Fluents are not supported') # TODO: warning check if using simultaneous_stream_plan with non-eager functions applied_streams, deferred_streams = partition_results( evaluations, stream_results, lambda r: False) opt_evaluations = apply_streams(evaluations, applied_streams) stream_domain, stream_result_from_name = add_stream_actions( domain, deferred_streams) if any(map(is_optimizer_result, stream_results)): goal_expression = add_unsatisfiable_to_goal(stream_domain, goal_expression) combined_plan, _ = solve_finite(opt_evaluations, goal_expression, stream_domain, unit_costs=unit_costs, **kwargs) if combined_plan is None: return None, INF stream_plan, action_plan = partition_plan(combined_plan, stream_result_from_name) function_plan = extract_function_plan(opt_evaluations, action_plan, domain, unit_costs) cost = get_plan_cost(opt_evaluations, action_plan, domain, unit_costs) combined_plan = stream_plan + function_plan + action_plan return combined_plan, cost
def relaxed_stream_plan(evaluations, goal_expression, domain, stream_results, negative, unit_costs, unit_efforts, effort_weight, debug=False, **kwargs): # TODO: alternatively could translate with stream actions on real opt_state and just discard them # TODO: only consider axioms that have stream conditions? applied_results, deferred_results = partition_results(evaluations, stream_results, apply_now=lambda r: not r.external.info.simultaneous) stream_domain, result_from_name = add_stream_actions(domain, deferred_results) node_from_atom = get_achieving_streams(evaluations, applied_results) opt_evaluations = apply_streams(evaluations, applied_results) # if n.effort < INF if any(map(is_optimizer_result, stream_results)): goal_expression = augment_goal(stream_domain, goal_expression) problem = get_problem(opt_evaluations, goal_expression, stream_domain, unit_costs) # begin_metric with Verbose(debug): instantiated = instantiate_task(task_from_domain_problem(stream_domain, problem)) if instantiated is None: return None, INF if (effort_weight is not None) or any(map(is_optimizer_result, applied_results)): add_stream_costs(node_from_atom, instantiated, unit_efforts, effort_weight) add_optimizer_axioms(stream_results, instantiated) with Verbose(debug): sas_task = sas_from_instantiated(instantiated) sas_task.metric = True #sas_task = sas_from_pddl(task) #action_plan, _ = serialized_solve_from_task(sas_task, debug=debug, **kwargs) action_plan, _ = abstrips_solve_from_task(sas_task, debug=debug, **kwargs) #action_plan, _ = abstrips_solve_from_task_sequential(sas_task, debug=debug, **kwargs) if action_plan is None: return None, INF applied_plan, function_plan = partition_external_plan(recover_stream_plan( evaluations, goal_expression, stream_domain, applied_results, action_plan, negative, unit_costs)) deferred_plan, action_plan = partition_plan(action_plan, result_from_name) stream_plan = applied_plan + deferred_plan + function_plan action_plan = obj_from_pddl_plan(action_plan) cost = get_plan_cost(opt_evaluations, action_plan, domain, unit_costs) combined_plan = stream_plan + action_plan return combined_plan, cost
def relaxed_stream_plan(evaluations, goal_expression, domain, all_results, negative, unit_efforts, effort_weight, max_effort, simultaneous=False, reachieve=True, unit_costs=False, debug=False, **kwargs): # TODO: alternatively could translate with stream actions on real opt_state and just discard them # TODO: only consider axioms that have stream conditions? applied_results, deferred_results = partition_results( evaluations, all_results, apply_now=lambda r: not (simultaneous or r.external.info.simultaneous)) stream_domain, result_from_name = add_stream_actions( domain, deferred_results) opt_evaluations = apply_streams(evaluations, applied_results) # if n.effort < INF if reachieve: achieved_results = { r for r in evaluations.values() if isinstance(r, Result) } init_evaluations = { e for e, r in evaluations.items() if r not in achieved_results } applied_results = achieved_results | set(applied_results) evaluations = init_evaluations # For clarity # TODO: could iteratively increase max_effort node_from_atom = get_achieving_streams(evaluations, applied_results, unit_efforts=unit_efforts, max_effort=max_effort) if using_optimizers(all_results): goal_expression = add_unsatisfiable_to_goal(stream_domain, goal_expression) problem = get_problem(opt_evaluations, goal_expression, stream_domain, unit_costs) # begin_metric with Verbose(debug): instantiated = instantiate_task( task_from_domain_problem(stream_domain, problem)) if instantiated is None: return None, INF cost_from_action = {action: action.cost for action in instantiated.actions} if (effort_weight is not None) or using_optimizers(applied_results): add_stream_efforts(node_from_atom, instantiated, effort_weight, unit_efforts=unit_efforts) add_optimizer_axioms(all_results, instantiated) action_from_name = rename_instantiated_actions(instantiated) with Verbose(debug): sas_task = sas_from_instantiated(instantiated) sas_task.metric = True # TODO: apply renaming to hierarchy as well # solve_from_task | serialized_solve_from_task | abstrips_solve_from_task | abstrips_solve_from_task_sequential action_plan, _ = solve_from_task(sas_task, debug=debug, **kwargs) if action_plan is None: return None, INF action_instances = [action_from_name[name] for name, _ in action_plan] cost = get_plan_cost(action_instances, cost_from_action, unit_costs) axiom_plans = recover_axioms_plans(instantiated, action_instances) applied_plan, function_plan = partition_external_plan( recover_stream_plan(evaluations, opt_evaluations, goal_expression, stream_domain, node_from_atom, action_instances, axiom_plans, negative, unit_costs)) #action_plan = obj_from_pddl_plan(parse_action(instance.name) for instance in action_instances) action_plan = obj_from_pddl_plan(map(pddl_from_instance, action_instances)) deferred_plan, action_plan = partition_plan(action_plan, result_from_name) stream_plan = applied_plan + deferred_plan + function_plan combined_plan = stream_plan + action_plan return combined_plan, cost
def recover_stream_plan(evaluations, goal_expression, domain, stream_results, action_plan, negative, unit_costs): import pddl import instantiate # Universally quantified conditions are converted into negative axioms # Existentially quantified conditions are made additional preconditions # Universally quantified effects are instantiated by doing the cartesian produce of types (slow) # Added effects cancel out removed effects real_task = task_from_domain_problem(domain, get_problem(evaluations, goal_expression, domain, unit_costs)) node_from_atom = get_achieving_streams(evaluations, stream_results) opt_evaluations = apply_streams(evaluations, stream_results) opt_task = task_from_domain_problem(domain, get_problem(opt_evaluations, goal_expression, domain, unit_costs)) function_assignments = {fact.fluent: fact.expression for fact in opt_task.init # init_facts if isinstance(fact, pddl.f_expression.FunctionAssignment)} type_to_objects = instantiate.get_objects_by_type(opt_task.objects, opt_task.types) results_from_head = get_results_from_head(opt_evaluations) action_instances = instantiate_actions(opt_task, type_to_objects, function_assignments, action_plan) negative_from_name = get_negative_predicates(negative) axioms_from_name = get_derived_predicates(opt_task.axioms) opt_task.init = set(opt_task.init) real_states = [set(real_task.init)] # TODO: had old way of doing this (~July 2018) preimage_plan = [] function_plan = set() for layer in action_instances: for pair, action_instance in layer: axiom_plan = extract_axiom_plan(opt_task, action_instance, negative_from_name, static_state=real_states[-1]) if axiom_plan is None: continue simplify_conditional_effects(real_states[-1], opt_task.init, action_instance, axioms_from_name) preimage_plan.extend(axiom_plan + [action_instance]) apply_action(opt_task.init, action_instance) real_states.append(set(real_states[-1])) apply_action(real_states[-1], action_instance) if not unit_costs and (pair is not None): function_result = extract_function_results(results_from_head, *pair) if function_result is not None: function_plan.add(function_result) break else: raise RuntimeError('No action instances are applicable') # TODO: could instead just accumulate difference between real and opt full_preimage = plan_preimage(preimage_plan, []) stream_preimage = set(full_preimage) - real_states[0] negative_preimage = set(filter(lambda a: a.predicate in negative_from_name, stream_preimage)) positive_preimage = stream_preimage - negative_preimage function_plan.update(convert_negative(negative_preimage, negative_from_name, full_preimage, real_states)) step_from_fact = {fact_from_fd(l): full_preimage[l] for l in positive_preimage if not l.negated} target_facts = list(step_from_fact.keys()) #stream_plan = reschedule_stream_plan(evaluations, target_facts, domain, stream_results) stream_plan = [] extract_stream_plan(node_from_atom, target_facts, stream_plan) stream_plan = prune_stream_plan(evaluations, stream_plan, target_facts) stream_plan = convert_fluent_streams(stream_plan, real_states, step_from_fact, node_from_atom) # visualize_constraints(map(fact_from_fd, stream_preimage)) if DO_RESCHEDULE: # TODO: detect this based on unique or not # TODO: maybe test if partial order between two ways of achieving facts, if not prune new_stream_plan = reschedule_stream_plan(evaluations, target_facts, domain, stream_plan) if new_stream_plan is not None: stream_plan = new_stream_plan return stream_plan + list(function_plan)