def test_triples(): assert len(triples(relationships([sequential('a', 'b'), sequential('b', 'c')])).items()) == 1 assert len(triples(relationships([sequential('a', 'b'), sequential('b', 'c'), sequential('c', 'd')])).items()) == 2
def test_exhaustive_consistent(): # check basic consistency assert consistent(var('a'), var('b'), sequential('a', 'b')) # see how long a causal loop can be before transitivity stops working for i in range(1, 5): clauses = [sequential(to_char(i), 'a')] + chain(i) assert not consistent(and_(*clauses), exhaustive=True)
def emission(self): """Sending a message must be preceded by observation of its ins, but cannot be preceded by observation of any nils or outs""" s = partial(observe, self.sender) ins = [impl(self.sent, sequential(s(p), self.sent)) for p in self.ins] nils = [impl(and_(self.sent, s(p)), sequential(self.sent, s(p))) for p in self.nils] outs = [impl(self.sent, simultaneous(s(p), self.sent)) for p in self.outs] return and_(*(ins + nils + outs))
def test_transitivity(): def trans(s): return transitivity(triples(relationships(s))) statements = [sequential('a', 'b'), sequential('b', 'c'), sequential('d', 'e')] assert len(trans(statements)) == 1 statements += sequential('a', 'c') assert trans(statements)[0].equiv( impl(and_(var("a<b"), var("b<c")), var("a<c")))
def reception(self): "Each message reception is accompanied by the observation of its parameters; either they are observed, or the message itself is not" clauses = [impl(self.received, or_(sequential(p, self.received), simultaneous(p, self.received))) for p in map(partial(observe, self.recipient), self.ins | self.outs)] return and_(*clauses)
def blocked(self): s = partial(observe, self.sender) ins = [~s(p) for p in self.ins] nils = [and_(s(p), ~(sequential(s(p), self.sent) | simultaneous(s(p), self.sent))) for p in self.nils] outs = [s(p) for p in self.outs] return or_(*(nils + outs + ins))
def test_timeline(): statements = [simultaneous('a', 'b'), sequential('b', 'a')] t = timeline(relationships(statements)) print('timeline: ', t) formula = and_(var('a'), var('b'), *(t + statements)) print('formula: ', formula) s = formula.sat()[1] if s: print('solution: ', [k for k, v in s.items() if v]) assert not s
def transmission(self): "Each message reception is causally preceded by its emission" return impl(self.received, sequential(self.sent, self.received))
def test_ordered(): assert not (ordered('a', 'b') & var('a') & var('b') & ~sequential('a', 'b') & ~sequential('b', 'a')).sat()[1]
def test_relationships(): statements = [simultaneous('a', 'b'), sequential('a', 'b')] rs = relationships(statements) assert ('a', 'b') in rs and len(rs[('a', 'b')]) == 2
def test_consistent2(): # see how long a causal loop can be before transitivity stops working for i in range(1, 5): clauses = [sequential(to_char(i), 'a')] + chain(i) assert not consistent(and_(*clauses))
def test_consistent(): # check basic consistency assert consistent(var('a'), var('b'), sequential('a', 'b'))
def chain(n): clauses = [] for i in range(n): clauses.append(sequential(to_char(i), to_char(i + 1))) return clauses