def __init__(self, ls: Union[Atom, Boolean, List[Atom], List[Boolean]] = None): new_typeset, loc = CoreMovement.process_input(ls) new_typeset, loc = CoreMovement.process_input(ls) lor = list(loc) lor.reverse() n = len(loc) f = [] """F(l1), F(l2), ...,F(ln)""" for l in loc: f.append(L.f_(l)) """F(l1) & F(l2) & ... & F(ln)""" f1 = L.and_(f) f2 = [] """1..n-1 !l_{i+1} U l_{i}""" for i, l in enumerate(loc[:n - 1]): f = L.u_(L.not_(loc[i + 1]), loc[i]) f2.append(f) f2 = L.and_(f2) f3 = [] """1..n-1 !l_{i} U l_{i} & X(!l_{i} U l_{i+1})""" for i, l in enumerate(loc[:n - 1]): f = L.u_(L.not_(loc[i]), L.and_([loc[i], L.x_(L.u_(L.not_(loc[i]), loc[i + 1]))])) f3.append(f) f3 = L.and_(f3) new_formula = L.and_([f1, f2, f3]) super().__init__(formula=(new_formula, new_typeset))
def context_active_rules(typeset: Typeset, output=None) -> Union[Atom, Tuple[List[str], Typeset]]: """Extract Liveness rules from the Formula""" rules_str = [] rules_typeset = Typeset() inputs, outs = typeset.extract_inputs_outputs() active_context_types = [] for t in inputs: if isinstance(t, Boolean): if t.kind == TypeKinds.ACTIVE or t.kind == TypeKinds.CONTEXT: active_context_types.append(t.name) rules_typeset |= Typeset({t}) if len(active_context_types) > 0: rules_str.append(Logic.g_(Logic.and_(active_context_types))) if len(rules_str) == 0: return None if output is not None and output == FormulaOutput.ListCNF: return rules_str, rules_typeset return Atom(formula=(Logic.and_(rules_str, brackets=True), rules_typeset), kind=AtomKind.LIVENESS_RULE)
def extract_mutex_rules(typeset: Typeset, output=None) -> Union[Atom, Tuple[List[str], Typeset]]: """Extract Mutex rules from the Formula""" rules_str = [] rules_typeset = Typeset() for mutex_group in typeset.mutex_types: or_elements = [] if len(mutex_group) > 1: for mutex_type in mutex_group: neg_group = mutex_group.symmetric_difference({mutex_type}) and_elements = [mutex_type.name] for elem in neg_group: and_elements.append(Logic.not_(elem.name)) or_elements.append(Logic.and_(and_elements, brackets=True)) rules_str.append(Logic.g_(Logic.or_(or_elements, brackets=False))) rules_typeset |= Typeset(mutex_group) if len(rules_str) == 0: return None if output is not None and output == FormulaOutput.ListCNF: return rules_str, rules_typeset return Atom(formula=(Logic.and_(rules_str, brackets=True), rules_typeset), kind=AtomKind.MUTEX_RULE)
def __init__(self, pre: Union[Atom, Boolean], post: Union[Atom, Boolean], active: Union[Atom, Boolean], context: Union[Atom, Boolean] = None): new_typeset, pre, post, context, active = Trigger.process_bin_contextual_input(pre, post, context, active) c = Logic.and_([context, active]) f = Logic.u_(Logic.or_([Logic.and_([c, pre]), Logic.not_(c)]), Logic.and_([c, post])) super().__init__(formula=(f, new_typeset))
def __init__(self, ls: Union[List[Atom], List[Boolean]] = None): new_typeset, loc = CoreMovement.process_input(ls) f = [] for l in loc: f.append(Logic.gf_(l)) super().__init__(formula=(Logic.and_(f), new_typeset))
def __init__(self, ls: Union[Atom, Boolean, List[Atom], List[Boolean]] = None): new_typeset, loc = CoreMovement.process_input(ls) f = [] """F(l1), F(l2), ...,F(ln)""" for l in loc: f.append(L.f_(l)) """F(l1) & F(l2) & ... & F(ln)""" new_formula = L.and_(f) super().__init__(formula=(new_formula, new_typeset))
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 __init__(self, ls: Union[List[Atom], List[Boolean]] = None): new_typeset, loc = CoreMovement.process_input(ls) lor = list(loc) lor.reverse() n = len(loc) f1 = Logic.f_(lor[0]) if len(ls) == 1: super().__init__(formula=(Logic.g_(f1), new_typeset)) return """GF(l1 & F(l2 & ... F(ln))))""" for l in lor[1:]: f2 = Logic.and_([l, f1]) f1 = Logic.f_(f2) f1 = Logic.g_(f1) f2 = [] """1..n-1 !l_{i+1} U l_{i}""" for i, l in enumerate(loc[:n - 1]): f = Logic.u_(Logic.not_(loc[i + 1]), loc[i]) f2.append(f) f2 = Logic.and_(f2) f3 = [] """1..n G(l_{(i+1)%n} -> X((!l_{(i+1)%n} U l_{i})))""" for i, l in enumerate(loc): f = Logic.g_( Logic.implies_( loc[(i + 1) % n], Logic.x_(Logic.u_(Logic.not_(loc[(i + 1) % n]), loc[i])))) f3.append(f) f3 = Logic.and_(f3) new_formula = Logic.and_([f1, f2, f3]) super().__init__(formula=(new_formula, new_typeset))
def __init__(self, pre: Union[Atom, Boolean], ls: Union[Atom, Boolean, List[Atom], List[Boolean]] = None): new_typeset_a, loc = CoreMovement.process_input(ls) new_typeset_b, condition = Trigger.process_uni_input(pre) f = [] """F(l1), F(l2), ...,F(ln)""" for l in loc: f.append(Logic.f_(l)) """F(l1) & F(l2) & ... & F(ln)""" new_formula = Logic.g_(Logic.implies_(condition, Logic.and_(f))) new_typeset = new_typeset_a | new_typeset_b super().__init__(formula=(new_formula, new_typeset))
def extract_refinement_rules(typeset: Typeset, output=None) -> Union[Atom, Tuple[List[str], Typeset]]: """Extract Refinement rules from the Formula""" rules_str = [] rules_typeset = Typeset() for key_type, set_super_types in typeset.super_types.items(): if isinstance(key_type, Boolean): for super_type in set_super_types: rules_str.append(Logic.g_(Logic.implies_(key_type.name, super_type.name))) rules_typeset |= Typeset({key_type}) rules_typeset |= Typeset(set_super_types) if len(rules_str) == 0: return None if output is not None and output == FormulaOutput.ListCNF: return rules_str, rules_typeset return Atom(formula=(Logic.and_(rules_str, brackets=True), rules_typeset), kind=AtomKind.MUTEX_RULE)
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
def extract_adjacency_rules(typeset: Typeset, output=None) -> Union[Atom, Tuple[List[str], Typeset]]: """Extract Adjacency rules from the Formula""" rules_str = [] rules_typeset = Typeset() for key_type, set_adjacent_types in typeset.adjacent_types.items(): if isinstance(key_type, Boolean): """G(a -> X(b | c | d))""" rules_str.append( Logic.g_(Logic.implies_(key_type.name, Logic.x_(Logic.or_([e.name for e in set_adjacent_types]))))) rules_typeset |= Typeset({key_type}) rules_typeset |= Typeset(set_adjacent_types) if len(rules_str) == 0: return None if output is not None and output == FormulaOutput.ListCNF: return rules_str, rules_typeset return Atom(formula=(Logic.and_(rules_str, brackets=True), rules_typeset), kind=AtomKind.ADJACENCY_RULE)
def parse_controller_specification_from_file( file_path: str) -> Tuple[str, str, str, str]: """Returns: assumptions, guarantees, inputs, outputs""" assumptions = [] guarantees = [] inputs = [] outputs = [] file_header = "" with open(file_path, 'r') as ifile: for line in ifile: line, header = StringMng._check_header(line) # skip empty lines if not line: continue # parse file header line elif header: if StringMng.ASSUMPTIONS_HEADER == line: if file_header == "": file_header = line else: Exception("File format not supported") elif StringMng.GUARANTEES_HEADER == line: if file_header == StringMng.ASSUMPTIONS_HEADER: file_header = line else: Exception("File format not supported") elif StringMng.INS_HEADER == line: if file_header == StringMng.GUARANTEES_HEADER: file_header = line else: Exception("File format not supported") elif StringMng.OUTS_HEADER == line: if file_header == StringMng.INS_HEADER: file_header = line else: Exception("File format not supported") elif StringMng.END_HEADER == line: if file_header == StringMng.OUTS_HEADER: if len(assumptions) == 0: assumptions.append("true") return Logic.and_(assumptions), Logic.and_( guarantees), ",".join(inputs), ",".join( outputs) else: Exception("File format not supported") else: raise Exception("Unexpected File Header: " + line) else: if StringMng.ASSUMPTIONS_HEADER == file_header: assumptions.append(line.strip()) if StringMng.GUARANTEES_HEADER == file_header: guarantees.append(line.strip()) if StringMng.INS_HEADER == file_header: inputs.append(line.strip()) if StringMng.OUTS_HEADER == file_header: outputs.append(line.strip())