def __getitem__(self,x): """ Return max(t(x) t in S), where each t is a min-term. :param x: the input """ Operation.check_input(self,x) return max([min([x[i] for i in s]) for s in self.S])
def __init__(self,arity,S=None,dom=2): """ Create a new min/max operation. """ Operation.__init__(self,arity,dom) # Default operation if S is None: S = frozenset(frozenset([i]) for i in range(arity)) self.S = frozenset(MinMax.sperner(map(lambda s: frozenset(s),S)))
def __getitem__(self,x): Operation.check_input(self,x) if x[0] == x[1]: return x[self.pos[0]] elif x[0] == x[2]: return x[self.pos[1]] elif x[1] == x[2]: return x[self.pos[2]] else: return self.vals[x]
def __eq__(self,other): if other.__class__.__name__ == "SharpTernary": return (self.dom == other.dom and self.pos == other.pos and self.vals == other.vals) else: return Operation.__eq__(self,other)
def __eq__(self,other): """ Test if this operation is equal to another. If the other operation is another instance MinMax, then we can simply compare the families of sets defining each. Otherwise, we use the more expensive compare method from Operation. :param other: The other operation. :type other: :class:`Operation` """ if other.__class__.__name__ == "MinMax": return self.S == other.S else: return Operation.__eq__(self,other)
def compose(self,F): """ Compose this operation with a list of operations. :param F: The operations to compose with. :type F: :class:`list` of :class:`Operation` If every element of F is a MinMax operation, then we can compute the composition using addition and multiplication (meet and join) of Sperner families. Otherwise, we use the more expensive implementation of compose from Operation, and return an ExplicitOperation object. """ if not min([f.__class__.__name__ == "MinMax" for f in F]): return Operation.compose(self,F) f = MinMax(F[0].arity,[],self.dom) for s in map(tuple,self.S): t = F[s[0]] for i in s[1:]: t = t * F[i] f = f + t return f
def __init__(self,dom,pos,vals): Operation.__init__(self,3,dom) self.pos = tuple(pos) self.vals = vals