def inEquality(self,node): #Check that: #-The constraint has two terms #-The constant on this constraint is 0 if 2==len(node.exp.terms) and 0==node.exp.const: #Get the two terms term1=node.exp.terms[0] term2=node.exp.terms[1] #Check for one variable expression and one function expression #If first term is a variable and second is a function if like_type(term1,VarExp) and like_type(term2,FuncExp): var=term1 func=term2 #If first term is a function and second is a variable elif like_type(term1,FuncExp) and like_type(term2,VarExp): var=term2 func=term1 else: var=None func=None #If one var and one function were found if var is not None and func is not None: #Make sure the coefficients are 1/-1 if (1==var.coeff or 1==func.coeff) and (var.coeff==-1*func.coeff): #Add the var=func mapping to the collection of equalities self.add_var_func_equality(var,func)
def __cmp__(self,other): #Functions are 'less' than IDs if like_type(other,VarExp): return 1 elif like_type(other,FuncExp): return cmp((self.coeff,self.name,self.args),(other.coeff,other.name,other.args)) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined."%(type(self),type(other)))
def __cmp__(self,other): #Compare other variables by their coefficients and ids if like_type(other,VarExp): return cmp((self.coeff,self.id),(other.coeff,other.id)) #Variables are 'greater' than functions elif like_type(other,FuncExp): return -1 else: raise ValueError("Comparison between a '%s' and a '%s' is undefined."%(type(self),type(other)))
def _get_formula_rename_dict(self, formula, other_formula): rename = {} # Make sure we are given a PresSet or a PresRelation raise_objs_not_like_types(formula, [PresSet, PresRelation]) # Make sure the two sets have the same arity if formula.arity() != other_formula.arity(): raise ValueError("The given formulas differ in arity") if like_type(formula, PresSet): from_vars = formula.tuple_set.vars to_vars = other_formula.tuple_set.vars for i in xrange(len(from_vars)): rename[from_vars[i].id] = to_vars[i].id else: from_vars = formula.tuple_in.vars to_vars = other_formula.tuple_in.vars for i in xrange(len(from_vars)): rename[from_vars[i].id] = to_vars[i].id from_vars = formula.tuple_out.vars to_vars = other_formula.tuple_out.vars for i in xrange(len(from_vars)): rename[from_vars[i].id] = to_vars[i].id return rename
def __mul__(self,other): if not like_type(other,NormExp): raise ValueError("Multiplication between a '%s' and a '%s' is undefined."%(type(self),type(other))) #Make sure one of the terms is only a constant and has no terms #Multiplication of variablies is undefined here if self._has_terms() and other._has_terms(): raise ValueError("Multiplication of variables/functions with other variables/functions is not defined."); self=deepcopy(self) other=deepcopy(other) #Swap self and other if necessary so that self is the constant expression if self._has_terms(): self,other=other,self const=self.const #Now do the multiplication of the variables, functions, and constant new_terms=[] for term in other.terms: new_terms.append(term*const) other.terms=new_terms other.const*=const return other
def inNormExp(self,node): #Check that: #-We are within a formula #-We are within an equality constraint #-We are not within a function's arguments #-The node only has 2 terms: For now we are looking for a=f(b)-like constraints if self.formula is not None and self.in_equality and 0==self.function_depth and 2==len(node.terms): #If first term is a variable and second is a function if like_type(node.terms[0],VarExp) and like_type(node.terms[1],FuncExp): var=node.terms[0] func=node.terms[1] #If first term is a function and second is a variable elif like_type(node.terms[0],FuncExp) and like_type(node.terms[1],VarExp): var=node.terms[1] func=node.terms[0] else: var=None func=None #If a var and a function were found if var is not None and func is not None: #Check that there is only one argument to the function # and that there is no constant: if 1==len(func.args) and 1==len(func.args[0].terms) and 0==func.args[0].const: func_arg=func.args[0].terms[0] #Check that: #-The single argument to the function is a VarExp #-This argument is a free variable #-The function is permutable if like_type(func_arg,VarExp) and self.formula.is_free_var(func_arg.id) and func.name in self.permutations: #Apply the rule a=f(b) -> b=f_inv(a) #Swap ids and coefficients var.id,func_arg.id=func_arg.id,var.id var.coeff,func_arg.coeff=func_arg.coeff,var.coeff #Save the function/inverse function names self.func_name=func.name self.func_inv_name=self.permutations[func.name] #Change the function name to its associated inverse name func.name=self.permutations[func.name] #Set the changed flag self.changed=True
def __add__(self,other): if not like_type(other,NormExp): raise ValueError("Addition between a '%s' and a '%s' is undefined."%(type(self),type(other))) self=deepcopy(self) other=deepcopy(other) #Add the terms from other to self (merging will happen during normalization) for term in other.terms: self.terms.append(term) #Add the constant value from other to self self.const+=other.const return self
def _get_prefix_rename_dict(self, formula, prefix): rename = {} # Make sure we are given a PresSet or a PresRelation raise_objs_not_like_types(formula, [PresSet, PresRelation]) if like_type(formula, PresSet): for var in formula.tuple_set.vars: rename[var.id] = prefix + "_" + var.id else: for var in formula.tuple_in.vars: rename[var.id] = prefix + "_in_" + var.id for var in formula.tuple_out.vars: rename[var.id] = prefix + "_out_" + var.id return rename
def union(self, other): # Make sure we weren't given the same object twice if self is other: raise ValueError("Cannot union a Set with itself") if like_type(other, Set): if self.arity() == other.arity(): selfcopy = deepcopy(self) other = deepcopy(other) selfcopy._add_set(other) else: raise ValueError( "Cannot union sets with differing arity: '%s' (arity %d) and '%s' (arity %d)" % (self, self.arity(), other, other.arity()) ) else: raise ValueError("Unsupported argument of type '%s' for operation union." % type(other)) self.print_debug("Set Union: %s.union(%s)=%s" % (self, other, selfcopy)) return selfcopy
def union(self, other): # Make sure we weren't given the same object twice if self is other: raise ValueError("Cannot union a Relation with itself") if like_type(other, Relation): if self.arity_in() == other.arity_in() and self.arity_out() == other.arity_out(): selfcopy = deepcopy(self) other = deepcopy(other) selfcopy._add_relation(other) else: raise ValueError( "Cannot union relations with differing arity ((%d->%d) and (%d->%d))." % (self.arity_in(), self.arity_out(), other.arity_in(), other.arity_out()) ) else: raise ValueError("Unsupported argument of type '%s' for operation union." % type(other)) self.print_debug("Relation Union: %s.union(%s)=%s" % (self, other, selfcopy)) return selfcopy
def __cmp__(self,other): #Compare VarTuples by their vars if like_type(other,VarTuple): return cmp(self.vars,other.vars) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined."%(type(self),type(other)))
def _add_relation(self, relation): if not like_type(relation, Relation): raise ValueError("Cannot add object of type '%s' to Relation." % type(relation)) self.relations.extend(relation.relations)
def __cmp__(self,other): if like_type(other,NormExp): return cmp((self.const,self.terms),(other.const,other.terms)) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined."%(type(self),type(other)))
def __cmp__(self,other): #Compare Constraints by their expression and Equality/Inequality type if like_type(other,Constraint): return cmp((self._equality,self.exp),(other._equality,other.exp)) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined."%(type(self),type(other)))
def __cmp__(self,other): #Compare Conjunctions by their constraintss if like_type(other,Conjunction): return cmp(self.constraints,other.constraints) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined."%(type(self),type(other)))
def __cmp__(self, other): # Compare Sets by their set collection if like_type(other, Set): return cmp(self.sets, other.sets) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined." % (type(self), type(other)))
def _add_set(self, set): if not like_type(set, Set): raise ValueError("Cannot add object of type '%s' to Set." % type(set)) self.sets.extend(set.sets)
def _vars(self): return [term for term in terms if like_type(term,VarExp)]
def __cmp__(self, other): # Compare Relations by their relation collection if like_type(other, Relation): return cmp(self.relations, other.relations) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined." % (type(self), type(other)))
def _funcs(self): return [term for term in self.terms if like_type(term,FuncExp)]
def __cmp__(self,other): if like_type(other,Symbolic): return cmp(self.name,other.name) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined."%(type(self),type(other)))
def __cmp__(self,other): #Compare PresRelations by their VarTuples, Conjunction, and Symbolics if like_type(other,PresRelation): return cmp((self.tuple_in,self.tuple_out,self.conjunct,self.symbolics),(other.tuple_in,self.tuple_out,other.conjunct,self.symbolics)) else: raise ValueError("Comparison between a '%s' and a '%s' is undefined."%(type(self),type(other)))