Example #1
0
    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)
Example #2
0
    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
Example #3
0
    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
Example #4
0
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",
Example #5
0
    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))
Example #6
0
    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
Example #7
0
 def name(self, value: str):
     self.__name, self.__id = StringMng.get_name_and_id(value)