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 prioritize_goal(first_priority_goal, second_priority_goal): pass """ Makes the assumption of one goal dependent on the satisfiability of the assumptions of the second goal """ variables = [] stronger_assumptions_list = [] for contract in first_priority_goal.contracts: variables |= contract.variables stronger_assumptions_list.append(And(contract.assumptions)) for contract in second_priority_goal.contracts: contract.add_variables(variables) contract.add_assumptions(Not(Or(stronger_assumptions_list)))
def check_satisfiability(variables: List[str], propositions: Union[List[str], str]) -> bool: if isinstance(propositions, str): propositions = [propositions] if len(propositions) == 1 and propositions[0] == "TRUE": return True if len(propositions) == 0: return True """Write the NuSMV file""" with open(smvfile, 'w') as ofile: ofile.write('MODULE main\n') ofile.write('VAR\n') for v in list(set(variables)): ofile.write('\t' + v + ";\n") ofile.write('\n') ofile.write('LTLSPEC ') ofile.write(str(Not(And(propositions)))) ofile.write('\n') try: output = subprocess.check_output( ['nuXmv', smvfile], encoding='UTF-8', stderr=subprocess.DEVNULL).splitlines() output = [ x for x in output if not (x[:3] == '***' or x[:7] == 'WARNING' or x == '') ] for line in output: if line[:16] == '-- specification': if 'is false' in line: print("\t\t\tSAT:\t" + str(And(propositions))) return True elif 'is true' in line: return False except Exception as e: with open(smvfile, 'r') as fin: print(fin.read()) raise e
def NotLTL(element: LTL) -> LTL: """Returns an str formula representing the logical AND of list_propoositions""" vars = element.variables formula = Not(element.formula) return LTL(formula, vars)
def negate(self): """Modifies the LTL formula with its negation""" self.__formula = Not(self.formula)
def __invert__(self): """Returns a new LTL with the negation of self""" formula = Not(self.formula) return LTL(formula=formula, variables=self.variables)
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