def intersection(self, other): self._typecheck(other, "intersect") other_states = self._make_delegate() other_states.update(superposition.getstates(other)) return type(self)(*(self._delegate & other_states))
def union(self, other): self._typecheck(other, "join") other_states = self._make_delegate() other_states.update(superposition.getstates(other)) other_states.update(self._delegate) return type(self)(*other_states)
def add_state(self, state): """Add state to this superposition. WARNING: this mutates the object (it's NOT copy on write). Unless you're absolutely certain of what you're doing, you most likely want to call superposition.state_union(sp, state) instead. """ for state_ in superposition.getstates(state): self._add_state(state_)
def GetState(self, item, **kwargs): states = [] for state in superposition.getstates(item): renderer = self.DelegateObjectRenderer(state) states.append(renderer.EncodeToJsonSafe(state)) if len(states) == 1: return states[0] return dict(states=states)
def render_row(self, target, **kwargs): states = [] for state in superposition.getstates(target): renderer = self.DelegateObjectRenderer(state) states.append(renderer.render_row(target=state, **kwargs)) if len(states) == 1: return states[0] joined = ", ".join([unicode(state) for state in states]) return text.Cell("(%d values): %s" % (len(states), joined))
def issuperset(self, other): if isinstance(other, type(self)): return self._delegate >= other._delegate if not superposition.insuperposition(other): return self.hasstate(superposition.getstate(other)) other_states = self._make_delegate() other_states.update(superposition.getstates(other)) return self._delegate >= other_states
def render_row(self, target, **kwargs): states = [] for state in superposition.getstates(target): renderer = self.DelegateObjectRenderer(state) states.append(renderer.render_row(target=state, **kwargs)) if len(states) == 1: return states[0] joined = ", ".join(sorted([unicode(state) for state in states])) return text.Cell("(%d values): %s" % (len(states), joined))
def visit_Let(self, expr, **_): saved_bindings = self.bindings if isinstance(expr, expression.LetAny): union_semantics = True elif isinstance(expr, expression.LetEach): union_semantics = False else: union_semantics = None if not isinstance(expr.context, expression.Binding): raise ValueError( "Left operand of Let must be a Binding expression.") # Context to rebind to. This is the key that will be selected from # current bindings and become the new bindings for ever subexpression. context = expr.context.value try: rebind = associative.resolve(saved_bindings, context) if not rebind: # No value from context. return None if union_semantics is None: # This is a simple let, which does not permit superposition # semantics. if superposition.insuperposition(rebind): raise TypeError( "A Let expression doesn't permit superposition " "semantics. Use LetEach or LetAny instead.") self.bindings = rebind return self.visit(expr.expression) # If we're using union or intersection semantics, the type of # rebind MUST be a Superposition, even if it happens to have # only one state. If the below throws a type error then the # query is invalid and should fail here. result = False for state in superposition.getstates(rebind): self.bindings = state result = self.visit(expr.expression) if result and union_semantics: return result if not result and not union_semantics: return False return result finally: self.bindings = saved_bindings
def testStates(self): """Test that states are inspectable and comparable.""" s1 = superposition.superposition("foo", "bar") s2 = superposition.superposition("bar", "foo") s3 = superposition.superposition(1, 2) s4 = 1 s5 = superposition.superposition(1) self.assertItemsEqual(superposition.getstates(s1), superposition.getstates(s2)) self.assertTrue(superposition.state_eq(s1, s2)) self.assertFalse(superposition.state_eq(s1, s3)) # Superposition is obviously not equal to a scalar. self.assertFalse(s5 == s4) # But their states CAN be equal: self.assertTrue(superposition.state_eq(s4, s5)) self.assertTrue(superposition.state_eq(s5, s4)) # We can also compare two scalars this way (if we really have nothing # better to do). self.assertTrue(superposition.state_eq("foo", "foo"))
def state_eq(self, other): if isinstance(other, type(self)): return self._delegate == other._delegate return sorted(self._delegate) == sorted(superposition.getstates(other))
def get_variants(self, key, complete=False): value = self.get(key, complete=complete) return superposition.getstates(value)