def extend(self, other: 'LTLs'): try: self.__formula = LTL(other.list[0].formula, other.list[0].variables) except Exception as e: print("WHT") raise e added_formulae = self.__formula.conjoin_with(other.list[1:]) self.list.extend(added_formulae)
def list(self, value: List['LTL']): if value is not None: self.__formula = LTL(value[0].formula, value[0].variables) added_formulae = self.__formula.conjoin_with(value[1:]) self.__list: List[LTL] = added_formulae else: self.__list = []
def extract_ltl_rules(context_rules: Dict) -> List[LTL]: """Dict: ltl_formula -> list_of_variables_involved""" ltl_list: List[LTL] = [] if "mutex" in context_rules: for cvars in context_rules["mutex"]: if len(cvars) > 0: variables: Variables = Variables() ltl = "G(" for vs in cvars: variables.extend(vs.variables) cvars_str = [n.formula for n in cvars] clauses = [] for vs_a in cvars_str: clause = [] clause.append(deepcopy(vs_a)) for vs_b in cvars_str: if vs_a is not vs_b: clause.append(Not(deepcopy(vs_b))) clauses.append(And(clause)) ltl += Or(clauses) ltl += ")" ltl_list.append(LTL(formula=ltl, variables=variables)) if "inclusion" in context_rules: for cvars in context_rules["inclusion"]: if len(cvars) > 0: variables: Variables = Variables() ltl = "G(" for i, vs in enumerate(cvars): variables.extend(vs.variables) ltl += str(vs) if i < (len(cvars) - 1): ltl += " -> " ltl += ")" ltl_list.append(LTL(formula=ltl, variables=variables)) if "liveness" in context_rules: for cvars in context_rules["liveness"]: variables: Variables = Variables() ltl = "G( F(" variables.extend(cvars.variables) ltl += str(cvars) ltl += "))" ltl_list.append(LTL(formula=ltl, variables=variables)) return ltl_list
def create_cgt(context_goals: Dict, rules: Dict) -> CGTGoal: """Compose all the set of goals in identified context""" composed_goals = [] for i, (ctx, goals) in enumerate(context_goals.items()): new_goals = deepcopy(goals) """Extracting the new context for the guarantees""" guarantees_ctx = [] for elem in ctx.cnf: if elem.kind == "context": pass else: guarantees_ctx.append(elem) guarantees_ctx = LTL(cnf=set(guarantees_ctx), skip_checks=True) """Setting the new context to each goal""" for g in new_goals: """Adding rules to each node""" g.apply_rules(rules) g.set_context(guarantees_ctx) try: ctx_goals = composition(new_goals) composed_goals.append(ctx_goals) except CGTFailException as e: print("FAILED OPE:\t" + e.failed_operation) print("FAILED MOT:\t" + e.failed_operation) print("GOALS_1:\t" + str([g.name for g in e.goals_involved_a])) print("GOALS_2:\t" + str([g.name for g in e.goals_involved_a])) """Conjoin the goals across all the mutually exclusive contexts""" cgt = conjunction(composed_goals, check_consistency=False) return cgt
def get_ltl_assumptions(self) -> LTL: a_list = [] vars = Variables() for c in self.contracts: a_list.append(c.assumptions.formula.formula) vars.extend(c.assumptions.formula.variables) new_formula = Or(a_list) return LTL(new_formula, vars)
def get_ltl_guarantees(self) -> LTL: g_list = [] vars = Variables() for c in self.contracts: g_list.append(c.guarantees.formula.formula) vars.extend(c.guarantees.formula.variables) new_formula = And(g_list) return LTL(new_formula, vars)
def remove(self, formulae: Union['LTL', List['LTL']]): if isinstance(formulae, LTL): formulae = [formulae] for formula in formulae: if formula in self.list: self.list.remove(formula) else: Exception("LTL formula not found, cannot be removed") if len(self.list) > 0: self.__formula = LTL(self.list[0].formula, self.list[0].variables) if len(self.list) > 1: self.__formula.conjoin_with(self.list[1:]) else: self.list = None
def get_ltl_guarantees(self) -> LTL: if len(self.contracts) > 1: """conjunction""" g_list = [] for c in self.contracts: g_list.append(c.guarantees) return LTL(cnf=set(g_list), skip_checks=True) else: """composition""" return self.contracts[0].guarantees
def __init__(self, assumptions: LTL = None, guarantees: LTL = None ): """List of assumptions in conjunction""" if assumptions is None: self.__assumptions = LTL() else: self.__assumptions = assumptions """List of guarantees in conjunction. All guarantees are saturated""" if guarantees is None: self.__guarantees = LTL() else: self.__guarantees = guarantees self.__guarantees.saturation = self.__assumptions self.check_feasibility()
def get_ltl_assumptions(self) -> LTL: if len(self.contracts) > 1: """conjunction""" a_list = [] vars = Variables() for c in self.contracts: a_list.append(c.assumptions.formula) vars |= c.assumptions.variables new_formula = Or(a_list) return LTL(new_formula, vars, skip_checks=True) else: """composition""" return self.contracts[0].assumptions
def __init__(self, formulae: List['LTL'], simplify=True): "formulae: list of formula to conjoin" "LTL formula" self.__formula: LTL = None "List of LTL formulae in conjunction that it is formed of" self.__list: List[LTL] = None if len(formulae) == 0: self.__formula: LTL = LTL("TRUE") self.__list: List[LTL] = [] else: if simplify: self.__formula: LTL = LTL(formulae[0].formula, formulae[0].variables) self.__list: List[LTL] = [formulae[0]] if len(formulae) > 1: try: added_formulae = self.__formula.conjoin_with(formulae[1:]) self.list.extend(added_formulae) except InconsistentException as e: raise e else: variables = Variables() formulae_str = [] for formula in formulae: variables.extend(formula.variables) formulae_str.append(formula.formula) try: self.__formula: LTL = LTL(And(formulae_str), variables) except InconsistentException as e: raise e self.__list: List[LTL] = formulae
def get_ltl_saturated_guarantees(self) -> LTL: assumptions_guarantee_pairs = [] vars = Variables() for c in self.contracts: assumptions_guarantee_pairs.append( (c.assumptions.formula.formula, c.guarantees.formula.formula)) vars.extend(c.assumptions.formula.variables) vars.extend(c.guarantees.formula.variables) new_formula = [] for ag_pairs in assumptions_guarantee_pairs: new_formula.append(Implies(ag_pairs[0], ag_pairs[1])) new_formula = And(new_formula) return LTL(new_formula, vars)
def __init__(self, patterns: List[LTL]): self.patterns = patterns variables = Variables() guarantees = set() for p in patterns: guarantees.add(p) # variables |= p.variables # guarantees.add(LTL(p.formula, p.variables)) guarantees = LTL(cnf=guarantees) super().__init__(guarantees=guarantees)
def merge_contexes(contexts: List[List[LTL]]) -> List[LTL]: """Merge the consistent contexts with conjunction""" contexts_merged: List[LTL] = [] print("\n\nMERGING " + str(len(contexts)) + " CONTEXTS...") for group in contexts: if len(group) > 0: """Extract formulas and check satisfiability, it also filters and simplify each context""" try: conj = LTL(cnf=set(group)) except InconsistentException: continue contexts_merged.append(conj) return contexts_merged
def __init__(self, name: str = None, description: str = None, contracts: List[Contract] = None, refined_by: List['CGTGoal'] = None, refined_with: str = None, context: Context = None): self.__connected_to = None if name is None: self.__name: str = "" else: self.__name: str = name if description is None: self.__description: str = "" else: self.__description: str = description if contracts is None: self.__contracts: List[Contract] = [] else: self.__contracts: List[Contract] = contracts if refined_by is None and refined_with is None: self.__refined_by = None self.__refined_with = None elif refined_by is not None and refined_with is not None: self.__refined_by: List['CGTGoal'] = refined_by self.__refined_with: str = refined_with for goal in refined_by: goal.connected_to = self else: raise AttributeError self.goal_context_to_show = LTL("TRUE") self.goal_context = [] if context is not None: self.set_context(context) print(self)
def __init__(self, assumptions_str: List[str], guarantees_str: List[str]): assumptions = set() guarantees = set() for a in assumptions_str: assumptions.add(LTL(a, Variables({Boolean(a)}))) for g in guarantees_str: guarantees.add(LTL(g, Variables({Boolean(g)}))) assumptions = LTL(cnf=assumptions) guarantees = LTL(cnf=guarantees) guarantees.saturate_with(assumptions) super().__init__(assumptions=assumptions, guarantees=guarantees)
def create_contextual_clusters(goals: List[CGTGoal], type: str, context_rules: List[LTL] = None) -> Dict: """Returns all combinations that are consistent""" if type == "MINIMAL": """LTL Creation""" """Among a pair of context combinations (two rows), save only the smaller context""" KEEP_SMALLER_COMBINATION = True """Goal Mapping""" """When mapping a goal context to a combination of context C, map if the goal context is satisfiable with C""" GOAL_CTX_SAT = False """When mapping a goal context to a combination of context C, map if the goal context is smaller than C""" GOAL_CTX_SMALLER = False """When more context points to the same set of goal take the smaller context""" SAVE_SMALLER_CONTEXT = False elif type == "MUTEX": """LTL Creation""" """Among a pair of context combinations (two rows), save only the smaller context""" KEEP_SMALLER_COMBINATION = False """Goal Mapping""" """When mapping a goal context to a combination of context C, map if the goal context is satisfiable with C""" GOAL_CTX_SAT = False """When mapping a goal context to a combination of context C, map if the goal context is smaller than C""" GOAL_CTX_SMALLER = False """When more context points to the same set of goal take the smaller context""" SAVE_SMALLER_CONTEXT = False else: raise Exception("The type is not supported, either MINIMAL or MUTEX") goals_flat = [] """Extract goals tjat are alreadu conjoined by the designer""" for goal in goals: if goal.refined_by is not None and goal.refined_with == "CONJUNCTION": goals_flat.extend(goal.refined_by) else: goals_flat.append(goal) goals = goals_flat """Extract all unique contexts""" contexts: List[LTL] = extract_unique_contexts_from_goals(goals) if len(contexts) == 0: return {LTL(): goals} print("\n\n\n\n" + str(len(goals)) + " GOALS\nCONTEXTS:" + str([str(c) for c in contexts])) print("\n\n") """Extract the combinations of all contextes and the combination with the negations of all the other contexts""" combs_all_contexts, combs_all_contexts_neg = extract_all_combinations_and_negations_from_contexts( contexts) context_goals = {} if type == "MINIMAL": context_goals = context_based_specification_clustering( combs_all_contexts, context_rules, goals, KEEP_SMALLER_COMBINATION, GOAL_CTX_SAT, GOAL_CTX_SMALLER, SAVE_SMALLER_CONTEXT) if type == "MUTEX": context_goals = context_based_specification_clustering( combs_all_contexts_neg, context_rules, goals, KEEP_SMALLER_COMBINATION, GOAL_CTX_SAT, GOAL_CTX_SMALLER, SAVE_SMALLER_CONTEXT) return context_goals
def __init__(self, guarantees: List[str], assumptions: List[str] = None): guarantees_obj = set() from typescogomo.variables import extract_variable for g in guarantees: guarantees_obj.add(LTL(g, extract_variable(g))) guarantees_obj = LTL(cnf=guarantees_obj) if assumptions is None: assumptions_obj = LTL() else: assumptions_obj = set() for a in assumptions: assumptions_obj.add(LTL(a, extract_variable(a))) assumptions_obj = LTL(cnf=assumptions_obj) guarantees_obj.saturate_with(assumptions_obj) super().__init__(assumptions=assumptions_obj, guarantees=guarantees_obj)
class LTLs: """List of LTL formulae in conjunction with each other""" def __init__(self, formulae: List['LTL'], simplify=True): "formulae: list of formula to conjoin" "LTL formula" self.__formula: LTL = None "List of LTL formulae in conjunction that it is formed of" self.__list: List[LTL] = None if len(formulae) == 0: self.__formula: LTL = LTL("TRUE") self.__list: List[LTL] = [] else: if simplify: self.__formula: LTL = LTL(formulae[0].formula, formulae[0].variables) self.__list: List[LTL] = [formulae[0]] if len(formulae) > 1: try: added_formulae = self.__formula.conjoin_with(formulae[1:]) self.list.extend(added_formulae) except InconsistentException as e: raise e else: variables = Variables() formulae_str = [] for formula in formulae: variables.extend(formula.variables) formulae_str.append(formula.formula) try: self.__formula: LTL = LTL(And(formulae_str), variables) except InconsistentException as e: raise e self.__list: List[LTL] = formulae @property def list(self): return self.__list @list.setter def list(self, value: List['LTL']): if value is not None: self.__formula = LTL(value[0].formula, value[0].variables) added_formulae = self.__formula.conjoin_with(value[1:]) self.__list: List[LTL] = added_formulae else: self.__list = [] @property def formula(self) -> LTL: return self.__formula @property def variables(self): return self.formula.variables def is_universe(self): return self.formula.is_true() def are_satisfiable_with(self, other: 'LTLs'): return self.formula.is_satisfiable_with(other.formula) def extend(self, other: 'LTLs'): try: self.__formula = LTL(other.list[0].formula, other.list[0].variables) except Exception as e: print("WHT") raise e added_formulae = self.__formula.conjoin_with(other.list[1:]) self.list.extend(added_formulae) def add(self, formulae: Union['LTL', List['LTL']]): added_formulae = self.formula.conjoin_with(formulae) self.list.extend(added_formulae) def remove(self, formulae: Union['LTL', List['LTL']]): if isinstance(formulae, LTL): formulae = [formulae] for formula in formulae: if formula in self.list: self.list.remove(formula) else: Exception("LTL formula not found, cannot be removed") if len(self.list) > 0: self.__formula = LTL(self.list[0].formula, self.list[0].variables) if len(self.list) > 1: self.__formula.conjoin_with(self.list[1:]) else: self.list = None def __str__(self): return str(self.formula)
def context(self): """Return a list of contexts, each is in OR with each other""" if len(self.goal_context) > 0: return self.goal_context else: return [LTL("TRUE")]
def extract_rules(rules: Dict) -> Dict: """Translates the rules in LTL formulae and returnes a dictionary of 5 cathegories""" """Dictionary to return""" rules_ltl = {} if "gridworld" in rules: rules_ltl["gridworld"] = [] for elem, adjacent in rules["gridworld"].items(): ltl = "G(" ltl += elem.formula + " -> X (" ltl += " | ".join([a.formula for a in adjacent]) ltl += "))" variables = Variables() variables |= elem.variables for a in adjacent: variables |= a.variables rules_ltl["gridworld"].append( LTL(formula=ltl, variables=variables, kind="gridworld")) if "context" in rules: rules_ltl["context"] = [] if "mutex" in rules["context"]: for mtx_elements in rules["context"]["mutex"]: if len(mtx_elements) > 0: variables: Variables = Variables() ltl = "G(" for vs in mtx_elements: variables |= vs.variables mtx_elements_str = [n.formula for n in mtx_elements] clauses = [] for vs_a in mtx_elements_str: clause = [deepcopy(vs_a)] for vs_b in mtx_elements_str: if vs_a is not vs_b: clause.append(Not(deepcopy(vs_b))) clauses.append(And(clause)) ltl += Or(clauses) ltl += ")" rules_ltl["context"].append( LTL(formula=ltl, variables=variables, kind="context")) if "inclusion" in rules["context"]: for pre, post in rules["context"]["inclusion"].items(): variables = Variables() variables |= pre.variables | post.variables ltl = "G((" + pre.formula + ") -> (" + post.formula + "))" rules_ltl["context"].append( LTL(formula=ltl, variables=variables, kind="context")) if "context_gridworld" in rules: rules_ltl["context_gridworld"] = [] for pre, post in rules["context_gridworld"].items(): variables = Variables() variables |= pre.variables | post.variables ltl = "G((" + pre.formula + ") -> (" + post.formula + "))" rules_ltl["context_gridworld"].append( LTL(formula=ltl, variables=variables, kind="context_gridworld")) if "constraints" in rules: rules_ltl["constraints"] = [] if "mutex" in rules["constraints"]: for mtx_elements in rules["constraints"]["mutex"]: if len(mtx_elements) > 0: variables: Variables = Variables() ltl = "G(" for vs in mtx_elements: variables |= vs.variables mtx_elements_str = [n.formula for n in mtx_elements] clauses = [] for vs_a in mtx_elements_str: clause = [deepcopy(vs_a)] for vs_b in mtx_elements_str: if vs_a is not vs_b: clause.append(Not(deepcopy(vs_b))) clauses.append(And(clause)) ltl += Or(clauses) ltl += ")" rules_ltl["constraints"].append( LTL(formula=ltl, variables=variables, kind="constraints")) if "inclusion" in rules["constraints"]: for pre, post in rules["constraints"]["inclusion"].items(): variables = Variables() variables |= pre.variables | post.variables ltl = "G((" + pre.formula + ") -> (" + post.formula + "))" rules_ltl["constraints"].append( LTL(formula=ltl, variables=variables, kind="constraints")) return rules_ltl