def _bool_interpretation_for_in(left_operand, right_operand, bool_value): assert type(bool_value) is bool if isinstance(left_operand, Variable) and isinstance(right_operand, (tuple, list, set, frozenset, range)) and len(right_operand) == 0: return None if isinstance(left_operand, (Variable, int, str)) and isinstance(right_operand, (set, frozenset, range)): # it is a unary constraint of the form x in/not in set/range ctr = Intension(Node.build(TypeNode.IN, left_operand, right_operand) if bool_value else Node.build(TypeNode.NOTIN, left_operand, right_operand)) elif isinstance(left_operand, PartialConstraint): # it is a partial form of constraint (sum, count, maximum, ...) ctr = ECtr(left_operand.constraint.set_condition(TypeConditionOperator.IN if bool_value else TypeConditionOperator.NOTIN, right_operand)) elif isinstance(right_operand, Automaton): # it is a regular constraint ctr = Regular(scope=left_operand, automaton=right_operand) elif isinstance(right_operand, MDD): # it is a MDD constraint ctr = Mdd(scope=left_operand, mdd=right_operand) elif isinstance(left_operand, int) and (is_1d_list(right_operand, Variable) or is_1d_tuple(right_operand, Variable)): ctr = Count(right_operand, value=left_operand, condition=(TypeConditionOperator.GE, 1)) # atLeast1 TODO to be replaced by a member/element constraint ? else: # It is a table constraint if not hasattr(left_operand, '__iter__'): left_operand = [left_operand] if not bool_value and len(right_operand) == 0: return None # TODO what to do if the table is empty and bool_value is true? an error message ? ctr = Extension(scope=list(left_operand), table=right_operand, positive=bool_value) return ctr
def __mod__(self, other): return Node.build(TypeNode.MOD, self, other)
def __rmul__(self, other): return Node.build(TypeNode.MUL, other, self)
def __rsub__(self, other): return Node.build(TypeNode.SUB, other, self)
def abs(*args): if len(args) == 1 and isinstance(args[0], Node) and args[0].type == TypeNode.SUB: return Node.build(TypeNode.DIST, *args[0].sons) return Node.build(TypeNode.ABS, *args) if len(args) == 1 and isinstance(args[0], (Node, Variable)) else absPython(*args)
def __invert__(self): return NotVariable(self) if isinstance(self, VariableInteger) else Node.build(TypeNode.NOT, self)
def __or__(self, other): return object.__or__(self, other) if None in {self, other} else Node.disjunction(self, other)
def __le__(self, other): if self is None or other is None: return object.__le__(self, other) return PartialConstraint.__ge__(other, self) if isinstance(other, PartialConstraint) else Node.build(TypeNode.LE, self, other)
def conjunction(*args): return Node.conjunction(*args)
def ift(*args): return Node.build(TypeNode.IF, *args)
def imply(*args): return Node.build(TypeNode.IMP, *args)
def xor(*args): return Node.build(TypeNode.XOR, *args) if len(args) > 1 else args[0]
def dist(*args): return Node.build(TypeNode.DIST, *args)
def max(*args): return Node.build(TypeNode.MAX, *args) if len(args) > 0 and any(isinstance(a, (Node, Variable)) for a in args) else maxPython(*args)
def __pow__(self, other): return Node.build(TypeNode.POW, self, other)
def __rfloordiv__(self, other): return Node.build(TypeNode.DIV, other, self)
def disjunction(*args): return Node.disjunction(*args)
def __ne__(self, other): if self is None or other is None: return object.__ne__(self, other) if isinstance(other, int) and other == 0 and isinstance(self, Node) and self.type == TypeNode.DIST: # we simplify the expression return Node.build(TypeNode.NE, self.sons[0], self.sons[1]) return PartialConstraint.__ne__(other, self) if isinstance(other, PartialConstraint) else Node.build(TypeNode.NE, self, other)
def __sub__(self, other): pair = self._simplify_operation(other) return Node.build( TypeNode.SUB, pair) if pair else PartialConstraint.combine_partial_objects( self, TypeNode.SUB, other)
def __and__(self, other): return object.__and__(self, other) if None in {self, other} else Node.conjunction(self, other)
def __radd__(self, other): return Node.build(TypeNode.ADD, other, self)
def __xor__(self, other): return object.__xor__(self, other) if None in {self, other} else Node.build(TypeNode.XOR, self, other)
def __sub__(self, other): if isinstance(other, PartialConstraint): return PartialConstraint.combine_partial_objects(self, TypeNode.SUB, other) return Node.build(TypeNode.SUB, self, other)