def setUp(self): self.check_realizable = lambda x: slugs.synthesize(x) is not None self.synthesize = slugs.synthesize self.f_un = GRSpec(env_vars="x", sys_vars="y", env_init="x", env_prog="x", sys_init="y", sys_safety=["y -> X(!y)", "!y -> X(y)"], sys_prog="y && x", moore=False, plus_one=False, qinit='\A \E') self.f = GRSpec( env_vars="x", sys_vars="y", env_init="x", env_prog="x", sys_init="y", sys_prog=["y & x", "!y"], moore=False, plus_one=False, ) self.dcounter = GRSpec(sys_vars={"y": (0, 5)}, sys_init=["y=0"], sys_prog=["y=0", "y=5"], moore=False, plus_one=False, qinit='\A \E')
def setUp(self): self.check_realizable = lambda x: slugs.synthesize(x) is not None self.synthesize = slugs.synthesize self.f_un = GRSpec(env_vars="x", sys_vars="y", env_init="x", env_prog="x", sys_init="y", sys_safety=["y -> X(!y)", "!y -> X(y)"], sys_prog="y && x", moore=False, plus_one=False, qinit='\A \E') self.f = GRSpec(env_vars="x", sys_vars="y", env_init="x", env_prog="x", sys_init="y", sys_prog=["y & x", "!y"], moore=False, plus_one=False, ) self.dcounter = GRSpec(sys_vars={"y": (0,5)}, sys_init=["y=0"], sys_prog=["y=0", "y=5"], moore=False, plus_one=False, qinit='\A \E')
def setUp(self): super(basic_test, self).setUp() self.check_realizable = lambda x: slugs.synthesize(x) is not None self.synthesize = slugs.synthesize
def synthesize_many(specs, ts=None, ignore_init=None, bool_actions=None, solver='gr1c'): """Synthesize from logic specs and multiple transition systems. The transition systems are composed synchronously, i.e., they all have to take a transition at each time step. The synchronous composition is obtained by taking the conjunction of the formulas describing each transition system. The states of each transition system can be either: - all integers, or - all strings In either case the transition system state will be represented in logic with a single variable, that ranges over a finite set of integers or strings, respectively. The keys of C{ts} are used to name each state variable. So the logic formula for C{ts['name']} will be C{'name'}. Who controls this state variable is determined from the attribute C{FTS.owner} that can take the values: - C{'env'} - C{'sys'} For example: >>> ts.states.add_from(xrange(4)) >>> ts['door'].owner = 'env' will result in a logic formula with an integer variable C{'door'} controlled by the environment and taking values over C{{0, 1, 2, 3}}. The example: >>> ts.states.add_from(['a', 'b', 'c']) >>> ts['door'].owner = 'sys' will instead result in a string variable C{'door'} controlled by the system and taking values over C{{'a', 'b', 'c'}}. @type specs: L{GRSpec} @type ts: C{dict} of L{FiniteTransitionSystem} @type ignore_init: C{set} of keys from C{ts} @type bool_actions: C{set} of keys from C{ts} @param solver: 'gr1c' or 'slugs' or 'jtlv' @type solver: str """ assert isinstance(ts, dict) for name, t in ts.iteritems(): assert isinstance(t, transys.FiniteTransitionSystem) ignore = name in ignore_init bool_act = name in bool_actions statevar = name if t.owner == 'sys': specs |= sys_to_spec(t, ignore, statevar, bool_actions=bool_act) elif t.owner == 'env': specs |= env_to_spec(t, ignore, statevar, bool_actions=bool_act) if solver == 'gr1c': ctrl = gr1c.synthesize(specs) elif solver == 'slugs': if slugs is None: raise ValueError('Import of slugs interface failed. ' + 'Please verify installation of "slugs".') ctrl = slugs.synthesize(specs) elif solver == 'jtlv': ctrl = jtlv.synthesize(specs) else: raise Exception('Unknown solver: ' + str(solver) + '. ' 'Available solvers: "jtlv", "gr1c", and "slugs"') try: logger.debug('Mealy machine has: n = ' + str(len(ctrl.states)) + ' states.') except: logger.debug('No Mealy machine returned.') # no controller found ? # counterstrategy not constructed by synthesize if not isinstance(ctrl, transys.MealyMachine): return None ctrl.remove_deadends() return ctrl
def synthesize( option, specs, env=None, sys=None, ignore_env_init=False, ignore_sys_init=False, bool_states=False, bool_actions=False, rm_deadends=True ): """Function to call the appropriate synthesis tool on the specification. The states of the transition system can be either: - all integers, or - all strings For more details of how the transition system is represented in logic look at L{synthesize_many}. Beware! ======= This function provides a generic interface to a variety of routines. Being under active development, the types of arguments supported and types of objects returned may change without notice. @param option: Magic string that declares what tool to invoke, what method to use, etc. Currently recognized forms: - C{"gr1c"}: use gr1c for GR(1) synthesis via L{interfaces.gr1c}. - C{"slugs"}: use slugs for GR(1) synthesis via L{interfaces.slugs}. - C{"jtlv"}: use JTLV for GR(1) synthesis via L{interfaces.jtlv}. @type specs: L{spec.GRSpec} @param env: A transition system describing the environment: - states controlled by environment - input: sys_actions - output: env_actions - initial states constrain the environment This constrains the transitions available to the environment, given the outputs from the system. @type env: L{FTS} @param sys: A transition system describing the system: - states controlled by the system - input: env_actions - output: sys_actions - initial states constrain the system @type sys: L{FTS} @param ignore_env_init: Ignore any initial state information contained in env. @type ignore_env_init: bool @param ignore_sys_init: Ignore any initial state information contained in sys. @type ignore_sys_init: bool @param bool_states: deprecated as inefficient if True, then use one bool variable for each state. Otherwise use a single integer variable for all states. @type bool_states: bool @param bool_actions: model actions using bool variables, otherwise use integers. @type bool_actions: bool @param rm_deadends: return a strategy that contains no terminal states. @type rm_deadends: bool @return: If spec is realizable, then return a Mealy machine implementing the strategy. Otherwise return None. @rtype: L{MealyMachine} or None """ specs = _spec_plus_sys( specs, env, sys, ignore_env_init, ignore_sys_init, bool_states, bool_actions) if option == 'gr1c': strategy = gr1c.synthesize(specs) elif option == 'slugs': if slugs is None: raise ValueError('Import of slugs interface failed. ' + 'Please verify installation of "slugs".') strategy = slugs.synthesize(specs) elif option == 'jtlv': strategy = jtlv.synthesize(specs) else: raise Exception('Undefined synthesis option. ' + 'Current options are "jtlv", "gr1c", and "slugs"') ctrl = strategy2mealy(strategy, specs) try: logger.debug('Mealy machine has: n = ' + str(len(ctrl.states)) + ' states.') except: logger.debug('No Mealy machine returned.') # no controller found ? # exploring unrealizability with counterexamples or other means # can be done by calling a dedicated other function, not this if not isinstance(ctrl, transys.MealyMachine): return None if rm_deadends: ctrl.remove_deadends() return ctrl