예제 #1
0
    def trap_predicate(self, number: int) -> mona.Formula:
        guard = self.guard_as_mona()
        variables = sorted([cast(mona.Variable, v.as_mona())
                            for v in self.free_variables], key=str)
        ports = self.ports.predicates
        free_pre = mona.Disjunction([p.hit_pre() for p in ports])
        free_post = mona.Disjunction([p.hit_post() for p in ports])
        safe_post: List[mona.Formula] = [free_post]

        broadcast_local: List[mona.Formula] = []
        if self.broadcasts:
            broadcasts_one_post = mona.Disjunction([b.one_post()
                                                    for b in self.broadcasts])
            safe_post.append(broadcasts_one_post)

            broadcasts_vertical = mona.Conjunction(
                    [cast(mona.Formula, mona.Negation(free_pre))] +
                    [b.vertical_hit() for b in self.broadcasts])
            broadcast_local.append(broadcasts_vertical)
        inner = mona.Disjunction([
            mona.Disjunction(safe_post),
            mona.Conjunction([mona.Negation(free_pre),
                              mona.Conjunction(broadcast_local)])
            ])
        formula = mona.UniversalFirstOrder(variables,
                                           mona.Implication(guard, inner))
        return mona.PredicateDefinition(f"trap_transition_{number}",
                                        self.system.state_variables,
                                        [], formula).simplify()
예제 #2
0
    def unique_intersection_predicate(self) -> mona.Formula:
        x = mona.Variable("x")
        y = mona.Variable("y")
        one_states = [mona.Variable(f"one{s}") for s in self.system.states]
        two_states = [mona.Variable(f"two{s}") for s in self.system.states]
        pairs = list(zip(one_states, two_states))

        statements: List[mona.Formula] = []
        # fix x in intersection of one state:
        for pair in pairs:
            pos = [cast(mona.Formula, mona.ElementIn(x, state))
                   for state in pair]
            different_pairs = [p for p in pairs if p != pair]
            neg = [  # negated statement from above
                    cast(mona.Formula, mona.Negation(
                        mona.Conjunction(
                            [mona.ElementIn(x, state) for state in pair])))
                    # for all other pairs
                    for pair in different_pairs]
            statements.append(mona.Conjunction(pos + neg))
        fix_x = mona.Disjunction(statements)
        # make sure x is unique:
        # y is in intersection
        y_in_intersection = mona.Disjunction([
            mona.Conjunction([mona.ElementIn(y, state) for state in pair])
            for pair in pairs])
        # y is x if y is in intersection
        unique_x = mona.UniversalFirstOrder(
                [y],
                mona.Implication(y_in_intersection, mona.Equal(x, y)))
        formula = mona.ExistentialFirstOrder([x], mona.Conjunction([fix_x,
                                                                    unique_x]))
        return mona.PredicateDefinition(
                "unique_intersection",
                one_states + two_states, [], formula).simplify()
예제 #3
0
 def marking_predicate(self) -> mona.Formula:
     m = mona.Variable("m")
     unique_in_component = mona.UniversalFirstOrder(
             [m],
             mona.Conjunction([
                 mona.Disjunction([
                     mona.Conjunction(
                         [cast(mona.Formula, mona.ElementIn(m, pos))]
                         + [cast(mona.Formula, mona.ElementNotIn(m, neg))
                            for neg in c.state_variables
                            if neg != pos])
                     for pos in c.state_variables])
                 for c in self.system.components]))
     flow_invariant = mona.PredicateCall("flow_invariant",
                                         self.system.state_variables)
     trap_invariant = mona.PredicateCall("trap_invariant",
                                         self.system.state_variables)
     return mona.PredicateDefinition(
             "marking",
             self.system.state_variables,
             [],
             mona.Conjunction([
                 unique_in_component,
                 flow_invariant,
                 trap_invariant,
             ])).simplify()
예제 #4
0
 def intersects_initial_predicate(self) -> mona.Formula:
     x = mona.Variable("x")
     initial_states = [mona.Variable(c.initial_state)
                       for c in self.system.components]
     x_initial = mona.Disjunction(
             [mona.ElementIn(x, init) for init in initial_states])
     formula = mona.ExistentialFirstOrder([x], x_initial)
     return mona.PredicateDefinition("intersects_initial",
                                     self.system.state_variables,
                                     [], formula).simplify()
예제 #5
0
 def deadlock_predicate(self) -> mona.Formula:
     inner = mona.Conjunction(
             [mona.PredicateCall(f"dead_transition_{number}",
                                 self.system.state_variables)
              for number in range(1, len(self.clauses) + 1)])
     return mona.PredicateDefinition(
             "deadlock",
             self.system.state_variables,
             [],
             inner).simplify()
예제 #6
0
 def initially_marked_trap_predicate(self) -> mona.Formula:
     inner = mona.Conjunction([
         mona.PredicateCall("trap",
                            self.system.state_variables),
         mona.PredicateCall("intersects_initial",
                            self.system.state_variables)])
     return mona.PredicateDefinition(
             "initially_marked_trap",
             self.system.state_variables,
             [],
             inner).simplify()
예제 #7
0
 def intersection_predicate(self) -> mona.Formula:
     x = mona.Variable("x")
     one_states = [mona.Variable(f"one{s}") for s in self.system.states]
     two_states = [mona.Variable(f"two{s}") for s in self.system.states]
     in_both_states = cast(List[mona.Formula],
                           [mona.Conjunction([mona.ElementIn(x, o),
                                              mona.ElementIn(x, t)])
                            for o, t in zip(one_states, two_states)])
     quantified_formula = mona.ExistentialFirstOrder(
             [x], mona.Disjunction(in_both_states))
     return mona.PredicateDefinition("intersection",
                                     one_states + two_states,
                                     [], quantified_formula
                                     ).simplify()
예제 #8
0
 def trap_invariant_predicate(self) -> mona.Formula:
     trap_states = [mona.Variable(f"T{s}") for s in self.system.states]
     precondition = mona.PredicateCall("initially_marked_trap", trap_states)
     postcondition = mona.PredicateCall(
             "intersection",
             trap_states + self.system.state_variables)
     return mona.PredicateDefinition(
             "trap_invariant",
             self.system.state_variables,
             [],
             mona.UniversalSecondOrder(trap_states,
                                       mona.Implication(precondition,
                                                        postcondition))
             ).simplify()
예제 #9
0
 def flow_invariant_predicate(self) -> mona.Formula:
     flow_states = [mona.Variable(f"F{s}") for s in self.system.states]
     precondition = mona.PredicateCall(
             "initially_uniquely_marked_flow",
             flow_states)
     postcondition = mona.PredicateCall(
             "unique_intersection",
             flow_states + self.system.state_variables)
     return mona.PredicateDefinition(
             "flow_invariant",
             self.system.state_variables,
             [], mona.UniversalSecondOrder(
                 flow_states, mona.Implication(precondition, postcondition))
             ).simplify()
예제 #10
0
 def is_dead_predicate(self, number: int) -> mona.Formula:
     dead_free = mona.Disjunction(
             [p.miss_pre() for p in self.ports.predicates])
     dead_broadcasts = mona.Disjunction(
             [b.is_dead() for b in self.broadcasts])
     guard = self.guard_as_mona()
     inner = mona.Implication(
             guard,
             mona.Disjunction([dead_free, dead_broadcasts]))
     formula = mona.UniversalFirstOrder([cast(mona.Variable, v.as_mona())
                                         for v in self.free_variables],
                                        inner)
     return mona.PredicateDefinition(f"dead_transition_{number}",
                                     self.system.state_variables,
                                     [], formula).simplify()
예제 #11
0
 def invariant_predicate(self, number: int) -> mona.Formula:
     inner = mona.Disjunction([
         # disjoint pre and post
         mona.Conjunction([self.disjoint_all_pre(),
                           self.disjoint_all_post()]),
         # unique pre and post
         mona.Conjunction([self.one_in_pre(), self.one_in_post()]),
         # more than one in pre
         mona.Conjunction([mona.Negation(self.disjoint_all_pre()),
                           mona.Negation(self.one_in_pre())]),
         ])
     variables = sorted([cast(mona.Variable, v.as_mona())
                         for v in self.free_variables], key=str)
     guard = self.guard_as_mona()
     quantification = mona.UniversalFirstOrder(
             variables,
             mona.Implication(guard, inner))
     return mona.PredicateDefinition(
             f"invariant_transition_{number}",
             self.system.state_variables,
             [],
             quantification).simplify()
예제 #12
0
 def uniquely_intersects_initial_predicate(self) -> mona.Formula:
     x = mona.Variable("x")
     y = mona.Variable("y")
     initial_states = [mona.Variable(c.initial_state)
                       for c in self.system.components]
     statements: List[mona.Formula] = []
     for init in initial_states:
         other_initial_states = [i for i in initial_states if i != init]
         x_only_in_init = mona.Conjunction(
                 [cast(mona.Formula, mona.ElementIn(x, init))]
                 + [cast(mona.Formula, mona.ElementNotIn(x, i))
                    for i in other_initial_states])
         statements.append(x_only_in_init)
     x_in_only_one_initial = mona.Disjunction(statements)
     y_in_initial = mona.Disjunction(
             [mona.ElementIn(y, i) for i in initial_states])
     x_unique = mona.UniversalFirstOrder([y], mona.Implication(
         y_in_initial, mona.Equal(x, y)))
     formula = mona.ExistentialFirstOrder(
             [x],
             mona.Conjunction([x_in_only_one_initial, x_unique]))
     return mona.PredicateDefinition(
             "uniquely_intersects_initial",
             self.system.state_variables, [], formula).simplify()
예제 #13
0
 def custom_property(self, name: str, formula: str) -> mona.Formula:
     return mona.PredicateDefinition(
             name,
             self.system.state_variables,
             [],
             mona.RawFormula(formula)).simplify()