예제 #1
0
def test_occurrence():
    occ = occurrence(relationships([simultaneous('a', 'b')]))
    print('occurrence: ', occ)
    formula = and_(simultaneous('a', 'b'), not_(var('a')), *occ)
    print('formula: ', formula)
    s = formula.sat()[1]
    if s:
        print('solution: ', [k for k, v in s.items() if v])
    assert not s
예제 #2
0
    def minimality(self, protocol):
        """Every parameter observed by a role must have a corresponding
        message transmission or reception"""
        sources = {}

        def add(m, p):
            if p in sources:
                sources[p].append(m)
            else:
                sources[p] = [m]

        outgoing = set()
        for m in self.messages(protocol).values():
            if m.recipient == self:
                for p in m.ins.union(m.outs):
                    add(m, p)
            else:
                for p in m.outs:
                    add(m, p)
                for p in m.ins:
                    outgoing.add(p)

        # keep track of 'in' parameters being sent without sources
        # unsourced parameters cannot be observed
        unsourced = [logic.Name(~self.observe(p), p)
                     for p in outgoing - set(sources.keys())]

        # sourced parameters must be received or sent to be observed
        sourced = [logic.Name(impl(self.observe(p),
                                   or_(*[simultaneous(self.observe(m), self.observe(p))
                                         for m in sources[p]])),
                              p)
                   for p in sources]

        return logic.And(*(unsourced + sourced))
예제 #3
0
 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)
예제 #4
0
 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))
예제 #5
0
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
예제 #6
0
 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))
예제 #7
0
    def uniqueness(self, key):
        "Bindings to key parameters uniquely identify enactments, so there should never be multiple messages with the same out key in the same enactment"

        candidates = set()
        for m in self.messages.values():
            if key in m.outs:
                candidates.add(simultaneous(
                    m.sent, observe(m.sender, key)))
        if candidates:
            return onehot0(*candidates)
        else:
            return True
예제 #8
0
def test_relationships():
    statements = [simultaneous('a', 'b'), sequential('a', 'b')]
    rs = relationships(statements)
    assert ('a', 'b') in rs and len(rs[('a', 'b')]) == 2