def realize_to_controller(self): """Realize the goal into a Controller object""" if self.controller is not None: return if self.session_name is None: folder_name = f"{self.s_controller_folder_name}/{self.goal_folder_name}" else: folder_name = f"{self.session_name}/{self.s_controller_folder_name}/{self.goal_folder_name}" try: controller_info = self.specification.get_controller_info() a, g, i, o = controller_info.get_strix_inputs() controller_synthesis_input = StringMng.get_controller_synthesis_str( controller_info) Store.save_to_file(controller_synthesis_input, "controller.txt", folder_name) realized, kiss_mealy, time = Strix.generate_controller(a, g, i, o) if not realized: controller_info = self.specification.get_controller_info( world_ts=self.__world.typeset) a, g, i, o = controller_info.get_strix_inputs() controller_synthesis_input = StringMng.get_controller_synthesis_str( controller_info) Store.save_to_file(controller_synthesis_input, "controller.txt", folder_name) realized, kiss_mealy, time = Strix.generate_controller( a, g, i, o) self.__realizable = realized if realized: Store.save_to_file(kiss_mealy, "controller_kiss", folder_name) # Store.generate_eps_from_dot(dot_mealy, "controller", folder_name) else: Store.save_to_file(kiss_mealy, "controller_inverted_kiss", folder_name) # Store.generate_eps_from_dot(dot_mealy, "controller_inverted", folder_name) self.__controller = Controller(mealy_machine=kiss_mealy, world=self.world, name=self.name, synth_time=time) print(f"NAME:\t{self.__name} ({self.__id})") print(self.__controller) Store.save_to_file(str(self.__controller), "controller_table", folder_name) except ControllerException as e: raise GoalSynthesisFail(self, e)
def get_strix_inputs(self) -> Tuple[str, str, str, str]: a = Logic.and_(list(itertools.chain( self.__assumptions, self.__a_mutex, self.__a_liveness ))) from tools.strings import StringMng a = StringMng.strix_syntax_fix(a) g = Logic.and_(list(itertools.chain( self.__guarantees, self.__g_mutex, self.__g_adjacency ))) g = StringMng.strix_syntax_fix(g) i = " ,".join(self.__inputs) o = " ,".join(self.__outputs) return a, g, i, o
def create_transition_controller(self, start: Types, finish: Types, t_trans: int) -> Controller: t_controller_name = f"TRANS_{start.name}->{finish.name}" if self.session_name is None: folder_name = f"{self.t_controllers_folder_name}/{t_controller_name}" else: folder_name = f"{self.session_name}/{self.t_controllers_folder_name}/{t_controller_name}" typeset = Typeset({start, finish}) realizable = False for n_steps in range(1, t_trans): trans_spec_str = Logic.and_([start.name, Logic.xn_(finish.name, n_steps)]) trans_spec = Atom(formula=(trans_spec_str, typeset)) trans_contract = Contract(guarantees=trans_spec) try: controller_info = trans_contract.get_controller_info(world_ts=self.world.typeset) a, g, i, o = controller_info.get_strix_inputs() controller_synthesis_input = StringMng.get_controller_synthesis_str(controller_info) Store.save_to_file(controller_synthesis_input, f"t_controller_{start.name}_{finish.name}_specs.txt", folder_name) realized, kiss_mealy, time = Strix.generate_controller(a, g, i, o) if realized: realizable = True break except ControllerException as e: raise TransSynthesisFail(self, e) if not realizable: raise Exception( f"Controller [{start.name}, {finish.name}] cannot be synthetized in {t_trans} steps") else: Store.save_to_file(kiss_mealy, f"{start.name}_{finish.name}_mealy", folder_name) # Store.generate_eps_from_dot(dot_mealy, f"{start.name}_{finish.name}_dot", # folder_name) t_controller = Controller(mealy_machine=kiss_mealy, world=self.world, name=t_controller_name, synth_time=time) Store.save_to_file(str(t_controller), f"{start.name}_{finish.name}_table", folder_name) return t_controller
from controller import Controller from tools.persistence import Persistence from tools.storage import Store from tools.strings import StringMng from tools.strix import Strix path = os.path.abspath(os.path.dirname(__file__)) if len(sys.argv) > 1: controller_name = sys.argv[1] else: controller_name = "5" print(f"controller selected: {path}/controller_specs/{controller_name}.txt") a, g, i, o = StringMng.parse_controller_specification_from_file( f"{path}/controller_specs/{controller_name}.txt") realizable, kiss_format, exec_time = Strix.generate_controller(a, g, i, o) controller = Controller(mealy_machine=kiss_format) Persistence.dump_controller(controller, f"{path}/controller_specs", controller_name) print("\n~~~MEALY MACHINE~~~\n" + str(controller)) Store.save_to_file(str(controller), f"{controller_name}_table.txt", absolute_folder_path=f"{path}/controller_specs") run = controller.simulate() print("\n\n\n~~~SIMULATION OF A RUN~~~\n" + run) Store.save_to_file(str(run), f"{controller_name}_run.txt",
def mealy_machine(self, value: str): self.__mealy_machine = value self.__states: List[str] = StringMng.get_states_from_kiss(value) self.__initial_state: str = StringMng.get_initial_state_from_kiss(value) self.__current_state = self.__initial_state inputs_str: List[str] = StringMng.get_inputs_from_kiss(value) self.__input_alphabet: List[Boolean] = [] for input in inputs_str: if self.world is not None: self.__input_alphabet.append(self.world.typeset[input]) else: self.__input_alphabet.append(Boolean(input)) outputs_str: List[str] = StringMng.get_outputs_from_kiss(value) self.__output_alphabet: List[Boolean] = [] for output in outputs_str: if self.world is not None: self.__output_alphabet.append(self.world.typeset[output]) else: self.__output_alphabet.append(Boolean(output)) """For each input and variables, returns the AP tuple corresponding to its true/false/dontcare assignment""" self.__inputs_ap: Dict[Boolean, Tuple[Atom, Atom, Atom]] = {} for input_type in self.__input_alphabet: atom = input_type.to_atom() self.__inputs_ap[input_type] = (atom, ~atom, atom.get_dontcare()) self.__outputs_ap: Dict[Boolean, Tuple[Atom, Atom, Atom]] = {} for output_type in self.__output_alphabet: atom = output_type.to_atom() self.__outputs_ap[output_type] = (atom, ~atom, atom.get_dontcare()) """Transition is from (inputs, state) to (state, output), i.e. I x S -> S x O""" self.__transitions: Dict[Tuple[Tuple[Atom], str], Tuple[str, Tuple[Tuple[Atom]]]] = {} for line in value.splitlines()[7:]: transition = line.split() if (len(self.__input_alphabet) == 0): input_str = "" cur_state_str = transition[0] next_state_str = transition[1] output_str_list = [] for element in transition[2:]: if "+" in element: continue output_str_list.append(element) else: input_str = transition[0] cur_state_str = transition[1] next_state_str = transition[2] output_str_list = [] for element in transition[3:]: if "+" in element: continue output_str_list.append(element) list_inputs: List[Atom] = [] for i, input in enumerate(input_str): if input == "1": list_inputs.append(self.__inputs_ap[self.__input_alphabet[i]][0]) elif input == "0": list_inputs.append(self.__inputs_ap[self.__input_alphabet[i]][1]) else: list_inputs.append(self.__inputs_ap[self.__input_alphabet[i]][2]) output_alternatives = [] for output_str in output_str_list: list_outputs: List[Atom] = [] for i, output in enumerate(output_str): if output == "1": list_outputs.append(self.__outputs_ap[self.__output_alphabet[i]][0]) elif output == "0": list_outputs.append(self.__outputs_ap[self.__output_alphabet[i]][1]) else: list_outputs.append(self.__outputs_ap[self.__output_alphabet[i]][2]) output_alternatives.append(tuple(list_outputs)) self.__transitions[(tuple(list_inputs), cur_state_str)] = (next_state_str, tuple(output_alternatives))
def generate_controller(assumptions: str, guarantees: str, ins: str, outs: str, kiss: bool = True) -> Tuple[bool, str, float]: """It returns: bool: indicating if a contorller has been synthetised str: mealy machine of the controller (if found) or of the counter-examples if not found in dot format float: indicating the controller time""" global command, timeout """Fix syntax""" assumptions = StringMng.strix_syntax_fix(assumptions) guarantees = StringMng.strix_syntax_fix(guarantees) print("\n\n") print(assumptions) print("\n") print(guarantees) print("\n") print(ins) print("\n") print(outs) print("\n\n") try: if ins == "": strix_specs = f"-f '{Logic.implies_(assumptions, guarantees)}' --outs='{outs}'" else: strix_specs = f"-f '{Logic.implies_(assumptions, guarantees)}' --ins='{ins}' --outs='{outs}'" if platform.system() != "Linux": strix_bin = "docker run pmallozzi/ltltools strix " else: strix_bin = "strix " if kiss: """Kiss format""" command = f"{strix_bin} --kiss {strix_specs}" else: """Dot format""" command = f"{strix_bin} --dot {strix_specs}" timeout = 3600 print("\n\nRUNNING COMMAND:\n\n" + command + "\n\n") start_time = time.time() result = subprocess.check_output([command], shell=True, timeout=timeout, encoding='UTF-8').splitlines() except subprocess.TimeoutExpired: raise SynthesisTimeout(command=command, timeout=timeout) except Exception as e: raise UnknownStrixResponse(command=command, response=e.output) exec_time = time.time() - start_time if "REALIZABLE" in result: realizable = True elif "UNREALIZABLE" in result: realizable = False else: raise UnknownStrixResponse(command=command, response="\n".join(result)) processed_return = "" if kiss: for i, line in enumerate(result): if ".inputs" not in line: continue else: processed_return = "\n".join(result[i:]) break else: for i, line in enumerate(result): if "digraph" not in line: continue else: processed_return = "".join(result[i:]) break return realizable, processed_return, exec_time
def name(self, value: str): self.__name, self.__id = StringMng.get_name_and_id(value)