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)
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)
def get_head(self): return f_expression.PrimitiveNumericExpression(self.name, self.parameters)