def remove(self, good_states, bad_states): """Delete pair (L, U) of good-bad sets of states. Note ==== Removing a pair which is not last changes the indices of all other pairs, because internally a list is used. The sets L,U themselves (good-bad) are required for the deletion, instead of an index, to prevent acceidental deletion of an unintended pair. Get the intended pair using __getitem__ first (or in any other way) and them call remove. If the pair is corrent, then the removal will be successful. See Also ======== add @param good_states: set of good states of this pair @type good_states: iterable container """ good_set = SubSet(self._states) good_set |= good_states bad_set = SubSet(self._states) bad_set |= bad_states self._pairs.remove((good_set, bad_set))
def subset_test(): a = SubSet([1, 2, 3, 4, {1: 2}]) print (a) a.add(1) a.add_from([1, 2]) a |= [3, 4] assert a._set == {1, 2, 3, 4} a |= [{1: 2}] assert a._list == [{1: 2}] b = SubSet([1, "2"]) b.add("2") assert b._set == {"2"} assert not bool(b._list) assert b._superset == [1, "2"] superset = [1, 2] s = SubSet(superset) s |= [1, 2] print (s) assert s._set == {1, 2} assert not bool(s._list) # s.add(3) return a
def add(self, good_states, bad_states): """Add new acceptance pair (L, U). See Also ======== remove, add_states, good, bad @param good_states: set L of good states for this pair @type good_states: container of valid states @param bad_states: set U of bad states for this pair @type bad_states: container of valid states """ good_set = SubSet(self._states) good_set |= good_states bad_set = SubSet(self._states) bad_set |= bad_states self._pairs.append((good_set, bad_set))
def __init__( self, deterministic=False, accepting_states_type=None, atomic_proposition_based=True, symbolic=False, ): """Initialize FiniteStateAutomaton. Additional keyword arguments are passed to L{LabeledDiGraph.__init__}. @param atomic_proposition_based: If False, then the alphabet is represented by a set. If True, then the alphabet is represented by a powerset 2^AP. """ self.atomic_proposition_based = atomic_proposition_based self.symbolic = symbolic # edge labeling if symbolic: alphabet = None # no checks else: if atomic_proposition_based: alphabet = PowerSet([]) self.atomic_propositions = alphabet.math_set else: alphabet = set() self.alphabet = alphabet edge_label_types = [{ 'name': 'letter', 'values': alphabet, 'setter': True }] super(FiniteStateAutomaton, self).__init__(edge_label_types=edge_label_types) # accepting states if accepting_states_type is None: self._accepting = SubSet(self.states) self._accepting_type = SubSet else: self._accepting = accepting_states_type(self) self._accepting_type = accepting_states_type self.states.accepting = self._accepting # used before label value self._transition_dot_label_format = { 'letter': '', 'type?label': '', 'separator': '\n' } self._transition_dot_mask = dict() self.dot_node_shape = {'normal': 'circle', 'accepting': 'doublecircle'} self.default_export_fname = 'fsa' self.automaton_type = 'Finite State Automaton'
def solve(ks, goal_label, spec): """Solve the minimum violation planning problem This follows from J. Tumova, G.C Hall, S. Karaman, E. Frazzoli and D. Rus. Least-violating Control Strategy Synthesis with Safety Rules, HSCC 2013. @param ks: the Kripke structure @param goal_label: a label in ks.atomic_propositions that indicates the goal @param spec: the prioritized safety specification of type tulip.spec.prioritized_safety.PrioritizedSpecification @return: (best_cost, best_path, weighted_product_automaton) where * best_cost is the optimal cost of reaching the goal * best_path is the optimal path to the goal * weighted_product_automaton is the weighted product automaton ks times spec """ assert isinstance(ks, KS) assert isinstance(spec, PrioritizedSpecification) assert ks.atomic_propositions == spec.atomic_propositions (wpa, null_state) = _construct_weighted_product_automaton(ks, spec) goal_states = [ state for state in ks.states if goal_label in ks.states[state]["ap"] ] accepting_goal_states = SubSet(wpa.states.accepting) accepting_goal_states.add_from(set(product(goal_states, spec.get_states()))) (cost, product_path) = dijkstra_multiple_sources_multiple_targets( wpa, wpa.states.initial, accepting_goal_states, cost_key="cost") state_path = [state[0] for state in product_path if state[0] != null_state] return (cost, state_path, product_path, wpa)
def initial(self, states): s = SubSet(self) s |= states self._initial = s
def subset_test(): a = SubSet([1, 2, 3, 4, {1: 2}]) print(a) a.add(1) a.add_from([1, 2]) a |= [3, 4] assert (a._set == {1, 2, 3, 4}) a |= [{1: 2}] assert (a._list == [{1: 2}]) b = SubSet([1, '2']) b.add('2') assert (b._set == {'2'}) assert (not bool(b._list)) assert (b._superset == [1, '2']) superset = [1, 2] s = SubSet(superset) s |= [1, 2] print(s) assert (s._set == {1, 2}) assert (not bool(s._list)) #s.add(3) return a