def solve(self):
        """
        Try to solve a set of constraints.  This sets up the
        initial constraint set, then splays all the possible
        primitives that move us close to solution.  Then it
        walks through all those in series to bring another
        solution generation, so on until one of the solution
        plans is successful, or there are no more primitives
        to consider moving us toward the goal.

        It returns (is_solvable, requires_input, plan), where
        solvable is the ability to solve the plan without any
        input, requires_input describes the ability to solve
        the plan if given some additional input, and plan is
        the considered solve plan
        """

        top_level = self
        current_leaves = [self]
        solution_node = None

        while(len(current_leaves) > 0 and not solution_node):
            new_leaves = []

            for leaf in current_leaves:
                solution_node = leaf.solve_one()
                # yeild to gevent
                gevent.sleep(0)
                if solution_node:
                    break

                # otherwise, we update our leaves and run
                # for solutions on leaves
                #
                # we'll have a bunch of single-level leaves,
                # or a single-path solution
                for child in leaf.children:
                    new_child = child

                    while len(new_child.children) > 0:
                        new_child = new_child.children[0]

                    new_leaves.append(new_child)
                    if new_child.found_solution():
                        solution_node = new_child

                # new_leaves = new_leaves + leaf.children

            if not solution_node:
                current_leaves = new_leaves
                top_level.print_tree()

        if solution_node:
            self.logger.debug('BEFORE BACKPRUNING')
            top_level.print_tree()

            while solution_node.parent:
                # backprune the solution
                solution_node.parent.children = [solution_node]
                solution_node = solution_node.parent

            # solution_node is now the root.
            # now we need to solve for args...
            plan = solution_node.plan()
            self.logger.debug(plan % "PLAN IS: %s")

            plan_solvable = True
            plan_choosable = False

            for step in plan:
                self.logger.debug('Solving args for step: %s' % step)
                prim = self._get_primitive_by_name(step['primitive'])
                if prim is None:
                    raise ValueError('cannot find prim in proposed plan. doh!')

                # terribleness below -- add in the task args if it is runtask
                #
                # this should really solve itself as a consequence of having
                # strong type knowledge, but as we have no strong knowledge
                # (or even weak type knowledge) we have to stuff this in
                # manually.  FIXME(rp): revisit this when we have types
                #
                # this should probably go away.

                addl_args = {}

                if prim['name'] == 'agent.run_task':
                    task_name = step['ns']['action']
                    task = [x for x in self.task_primitives.values()
                            if x['task_name'] == task_name]
                    if len(task) == 1:
                        addl_args = task[0]['args']

                self.logger.debug('discovered additional args: %s' % addl_args)

                addl_args.update(prim['args'])

                self.logger.debug('total args: %s' % addl_args)

                eval_args = dict([[x, addl_args[x]] for x in addl_args if
                                  addl_args[x]['type'] == 'evaluated'])
                other_args = dict([[x, addl_args[x]] for x in addl_args if
                                   addl_args[x]['type'] != 'evaluated'])

                for arg in other_args:
                    # walk through and see if we can solve this.
                    # man, this is stupid ugly
                    solvable, msg, choices = self.solve_arg(arg,
                                                            addl_args[arg],
                                                            step['ns'])
                    argv = addl_args[arg]
                    if solvable:
                        step['ns'][arg] = choices
                    elif choices:
                        plan_choosable = True
                        if(argv['required']):
                            plan_solvable = False
                        if not 'args' in step:
                            step['args'] = {}
                        step['args'][arg] = argv
                        step['args'][arg]['options'] = choices
                        step['args'][arg]['message'] = msg
                    else:
                        plan_choosable = True
                        if argv['required'] is True:
                            plan_solvable = False

                        if not 'args' in step:
                            step['args'] = {}
                        step['args'][arg] = argv
                        step['args'][arg]['message'] = msg

                if plan_solvable:
                    # express the evaluated args
                    eval_ns = {}
                    for k, v in step['ns'].items():
                        eval_ns[k] = v

                    node = self.base_api._model_get_by_id('nodes',
                                                          self.node_id)
                    nodes = self.base_api._model_get_all('nodes')

                    eval_ns['self'] = node
                    eval_ns['nodes'] = dict([(str(x['id']), x) for x in nodes])

                    # we've poked all the solved args into the ns,
                    # now, let's express them
                    for arg, val in eval_args.items():
                        if arg not in step['ns']:
                            self.logger.debug('expressing %s' %
                                              val['expression'])

                            # really, some of these should get bound at
                            # adventureate time... this is kind of wrong
                            step['ns'][arg] = \
                                opencenter.webapp.ast.apply_expression(
                                    eval_ns, val['expression'], self.base_api)

            self.logger.debug('returning (%s, %s, %s)' % (plan_solvable,
                                                          plan_choosable,
                                                          plan))
            return plan_solvable, plan_choosable, plan
        else:
            return False, False, []
dataset/ETHPy150Open rcbops/opencenter/opencenter/webapp/solver.py/Solver.solve/swapped operands of `%`