Ejemplo n.º 1
0
    def get_derived_function(self,exp):
        def get_default_variables(nr):
            return [conditions.Variable("?v%s" % varnr) for varnr in range(nr)]
        def get_new_symbol(key):
            # introduce new derived function symbol
            used_names = [axiom.name for axiom in self.functions.values()]
            for counter in itertools.count(1):
                new_func_name = "derived!" + str(counter)
                if new_func_name not in used_names:
                    Task.FUNCTION_SYMBOLS[new_func_name]="number"
                    return new_func_name

        assert isinstance(exp,f_expression.FunctionalExpression)
        if isinstance(exp,f_expression.PrimitiveNumericExpression):
            return exp
        elif isinstance(exp,f_expression.NumericConstant):
            key = (exp.value,)
            if key not in self.functions:
                symbol = get_new_symbol(key)
                self.functions[key] = axioms.NumericAxiom(symbol,[],None,[exp])
            args = ()
        elif isinstance(exp,f_expression.AdditiveInverse):
            subexp = self.get_derived_function(exp.parts[0])
            key = (exp.op, subexp.symbol)
            args = subexp.args
            if key not in self.functions:
                symbol = get_new_symbol(key)
                default_args = get_default_variables(len(subexp.args))
                subexp = f_expression.PrimitiveNumericExpression(subexp.symbol, default_args)
                self.functions[key] = axioms.NumericAxiom(symbol, default_args, exp.op, [subexp])
        else:
            # MR: Here if the expression has more than two arguments,
            # it needs to be properly handled, looping on the parts.
            # e.g. if one writes in the preconditions (* (A a) (* (B
            # b) (C c))) it needs to be converted in a proper way!
            assert (isinstance(exp,f_expression.ArithmeticExpression) and
                    len(exp.parts) == 2)

            pne1 = self.get_derived_function(exp.parts[0])
            pne2 = self.get_derived_function(exp.parts[1])
            key = (exp.op, pne1.symbol, pne2.symbol)
            args = pne1.args + pne2.args
            if key not in self.functions:
                if exp.op in ("+","*"):
                    key = (exp.op, pne2.symbol, pne1.symbol)
                    pne1,pne2 = pne2,pne1
                    args = pne1.args + pne2.args
                if key not in self.functions:
                    symbol = get_new_symbol(key)
                    default_args = get_default_variables(len(args))
                    pne1 = f_expression.PrimitiveNumericExpression(pne1.symbol,
                                                default_args[:len(pne1.args)])
                    if pne2.args:
                        pne2 = f_expression.PrimitiveNumericExpression(pne2.symbol,
                                                default_args[-len(pne2.args):])

                    self.functions[key] = axioms.NumericAxiom(symbol, tuple(default_args),
                                                              exp.op,[pne1,pne2])
        pne_symbol = self.functions[key].get_head().symbol
        return f_expression.PrimitiveNumericExpression(pne_symbol,args)
Ejemplo n.º 2
0
 def instantiate(self, var_mapping, fluent_functions, init_function_vals,
                 task, new_constant_axioms):
     arg_list = [
         var_mapping[conditions.Variable(par.name)]
         for par in self.parameters
     ]
     name = "(%s %s)" % (self.name, " ".join([arg.name
                                              for arg in arg_list]))
     parts = []
     for part in self.parts:
         if isinstance(part, f_expression.NumericConstant):
             parts.append(part)
         else:
             parts.append(
                 part.instantiate(var_mapping, fluent_functions,
                                  init_function_vals, task,
                                  new_constant_axioms))
     effect = f_expression.PrimitiveNumericExpression(self.name, arg_list)
     return PropositionalNumericAxiom(name, self.op, parts, effect)
Ejemplo n.º 3
0
 def get_head(self):
     return f_expression.PrimitiveNumericExpression(self.name,
                                                    self.parameters)