Esempio n. 1
0
def generate_controller_from_cgt(cgt: CGTGoal, folder_path):
    assum = []
    guaran = []

    for elem in cgt.get_ltl_assumptions().cnf:
        assum.append(elem.formula)

    guaran.append(cgt.get_ltl_guarantees().formula)
    # for elem in cgt.get_ltl_guarantees().cnf:
    #     guaran.append(elem.formula)

    uncontrollable = []
    controllable = []

    variables = cgt.get_variables()
    for var in variables:
        if var.controllable:
            controllable.append(var.name)
        else:
            uncontrollable.append(var.name)

    save_to_file(generate_controller_input_text(assum, guaran, uncontrollable, controllable),
                 folder_path + "specification.txt")

    exec_time = 0.0
    realizable = False
    mealy_machine = None

    realizable, mealy_machine, exec_time = create_controller_if_exists(folder_path + "specification.txt")

    return realizable, mealy_machine, exec_time
Esempio n. 2
0
def generate_buchi(formula: LTL, file_path: str):
    # if platform.system() != "Linux":
    #     print(platform.system() + " is not supported for buchi generation")
    #     return
    try:

        dot_file_path = os.path.dirname(file_path)
        if dot_file_path == "":
            file_path = results_folder + file_path

        print(formula)
        b_formula, new_vars, old_vars = traslate_boolean(formula.formula)
        print(b_formula)
        result = subprocess.check_output(
            ["ltl2tgba", "-B", b_formula, "-d"],
            encoding='UTF-8',
            stderr=subprocess.DEVNULL).splitlines()
        result = [x for x in result if not ('[Büchi]' in x)]
        result = "".join(result)

        dot_file_path = os.path.dirname(file_path)
        dot_file_name = os.path.splitext(file_path)[0]

        save_to_file(result, dot_file_name + ".dot")
        src = Source(result,
                     directory=dot_file_path,
                     filename=dot_file_name,
                     format="eps")
        src.render(cleanup=True)
        print(dot_file_name + ".eps  ->   buchi generated")

    except Exception as e:
        raise e
Esempio n. 3
0
def create_general_controller_from_goals(goals: List[CGTGoal],
                                         folder_path: str, type: str):
    assumptions = []
    guarantees = []
    inputs = set()
    outputs = set()

    for goal in goals:
        assum, guaran, ins, outs = generate_general_controller_inputs_from_goal(
            ap, rules, goal, complete=True)
        assumptions.extend(assum)
        guarantees.extend(guaran)
        inputs.update(set(ins))
        outputs.update(set(outs))

    controller_file_name = folder_path + "specification.txt"
    if type == "AND":
        save_to_file(
            generate_controller_input_text(assumptions, guarantees,
                                           list(inputs), list(outputs)),
            controller_file_name)

    elif type == "OR":
        save_to_file(
            generate_controller_input_text([Or(assumptions)], guarantees,
                                           list(inputs), list(outputs)),
            controller_file_name)

    else:
        raise Exception("type error, either AND or OR")

    controller_generated = False
    trivial = False
    exec_time = 0.0
    try:
        controller_generated, exec_time = create_controller_if_exists(
            controller_file_name)
    except SynthesisException as e:
        if e.os_not_supported:
            print("Os not supported for synthesis. Only linux can run strix")
        elif e.trivial:
            trivial = True
            controller_generated = True
            print(
                "The assumptions are not satisfiable. The controller is trivial."
            )

    return controller_generated, trivial, exec_time
Esempio n. 4
0
def create_controller_if_exists(
        controller_input_file: str) -> Tuple[bool, str, float]:
    """Return true if controller has been synthesized False otherwise.
    It also return the time needed"""

    if platform.system() != "Linux":
        print(platform.system() + " is not supported for synthesis")
        raise SynthesisException("os_not_supported")

    print("controller_input_file: " + controller_input_file)
    a, g, i, o = parse_controller(controller_input_file)

    # variables = [var.strip() + ": boolean" for var in i.split(',')]
    # assumptions_satisfiable = check_satisfiability(variables, a)
    #
    # if not assumptions_satisfiable:
    #     raise SynthesisException("trivial")

    mealy_machine, exec_time = get_controller(a, g, i, o)

    if mealy_machine.startswith("UNREALIZABLE"):
        print("UNREALIZABLE")
        return False, None, exec_time

    print(controller_input_file + " IS REALIZABLE")
    dot_file_path = os.path.dirname(controller_input_file)
    dot_file_name = os.path.splitext(controller_input_file)[0]

    dot_file_name = dot_file_name.replace("specification", "controller")

    save_to_file(mealy_machine, dot_file_name + ".dot")
    print("DOT file generated")

    src = Source(mealy_machine,
                 directory=dot_file_path,
                 filename=dot_file_name,
                 format="eps")
    src.render(cleanup=True)
    print(dot_file_name + ".eps  ->   mealy machine generated")
    return True, mealy_machine, exec_time
Esempio n. 5
0
def generate_controller_from_cgt(cgt: CGTGoal, folder_path, complete):
    assum, guaran, ins, outs = generate_general_controller_inputs_from_goal(
        ap, rules, cgt, complete)
    save_to_file(generate_controller_input_text(assum, guaran, ins, outs),
                 folder_path + "specification.txt")

    exec_time = 0.0
    realizable = False
    try:
        controller_generated, exec_time = create_controller_if_exists(
            folder_path + "specification.txt")
        realizable = controller_generated

    except SynthesisException as e:
        if e.os_not_supported:
            print("Os not supported for synthesis. Only linux can run strix")
        elif e.trivial:
            print(
                "The assumptions are not satisfiable. The controller is trivial."
            )
            raise Exception(
                "Assumptions unsatisfiable in a CGT is impossible.")

    return realizable, exec_time
Esempio n. 6
0
def run(list_of_goals: List[CGTGoal], result_folder: str):
    """Print List of Goals"""
    for g in list_of_goals:
        print(g)

    rules_dict = extract_rules(rules)

    for k, v in rules_dict.items():
        print(k)
        for elem in v:
            print(elem)

    """Create new mutex clusters and assign them to the goals"""
    context_goals = create_contextual_clusters(list_of_goals, "MUTEX", rules_dict["context"])

    """Create the CGT based on the clusters"""
    try:
        cgt = create_cgt(context_goals, rules_dict)
    except CGTFailException as e:
        print(pretty_cgt_exception(e))
        sys.exit()

    save_to_file(str(cgt), result_folder + "/CGT_clustered.txt")
    save_to_file(str(cgt.print_cgt_detailed()), result_folder + "/CGT_clustered_details.txt")


    """Try to extent every leaf of the CGT by mapping to the library"""
    try:
        extend_cgt(cgt, library, rules_dict)
    except CGTFailException as e:
        print(pretty_cgt_exception(e))
        sys.exit()

    save_to_file(str(cgt), result_folder + "/CGT_refined.txt")
    save_to_file(str(cgt.print_cgt_detailed()), result_folder + "/CGT_refined_detailed.txt")

    save_to_file(str(cgt.print_cgt_summary()), result_folder + "/CGT_summary.txt")

    """Generate a controller for each node of the CGT"""
    generate_controllers_for_cgt(cgt, result_folder + "/all_goals/")

    save_to_file(str(cgt.print_cgt_summary()), result_folder + "/CGT_summary.txt")
    save_to_file(str(cgt.pretty_print_cgt_summary()), result_folder + "/CGT_summary_pretty.txt")

    print(cgt)
Esempio n. 7
0
def run(list_of_goals: List[CGTGoal],
        result_folder: str,
        general_and=False,
        general_or=False,
        no_clusters=False,
        clusters_origianl=False,
        clusters_mutex=False,
        complete=True):
    """Print List of Goals"""
    for g in list_of_goals:
        print(g)

    controller_generated_and = False
    trivial_and = False
    controller_generated_or = False
    trivial_or = False
    realizable_no_clusters = False
    no_clusters_exec_time = 0.0
    realizables_clustered = []
    exec_times_clustered = []
    realizables_original = []
    exec_times_original = []

    goals_res = ""
    for g in list_of_goals:
        """Generate controller from goals as is, where the assumptions are in AND"""
        controller, trivial, exec_time = create_general_controller_from_goals(
            [g], result_folder + "/goal_list/" + g.name + "/", "AND")
        if controller:
            goals_res += g.name + "\t" + "YES\t" + format(exec_time,
                                                          '.3f') + "sec\n"
        else:
            goals_res += g.name + "\t" + "NO\t" + format(exec_time,
                                                         '.3f') + "sec\n"

    summary_file_name = result_folder + "/SUMMARY.txt"
    dirname = os.path.dirname(summary_file_name)
    if not os.path.exists(dirname):
        os.makedirs(dirname)
    with open(summary_file_name, 'w') as f:
        f.write(pretty_print_goals(ap, rules, goals))
        f.write("\nREALIZABILITY OF INDIVIDUAL GOALS\n" + goals_res)
    f.close()

    if general_and:
        """Generate controller from goals as is, where the assumptions are in AND"""
        controller_generated_and, trivial_and, exec_time_and = create_general_controller_from_goals(
            list_of_goals, result_folder + "/general_with_and/", "AND")

        ret = "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
        ret += "GENERAL SPECIFICATION WITH ALL GAOLS: **AND** OF ASSUMPTIONS **AND** OF GUARANTEES\n"
        ret += "-->\t" + str(len(list_of_goals)) + " goals: " + str(
            [c.name for c in list_of_goals]) + "\n"
        if controller_generated_and:
            ret += "REALIZABLE\tYES\t\t" + format(exec_time_and,
                                                  '.3f') + "sec\n"
        else:
            ret += "REALIZABLE\tNO\t\t" + format(exec_time_and,
                                                 '.3f') + "sec\n"
        if trivial_and:
            ret += "TRIVIAL\tYES\t\t\n"
        else:
            ret += "TRIVIAL\tNO\t\t\n"
        ret += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
        f = open(summary_file_name, "a+")
        f.write(ret)
        f.close()

    if general_or:
        """Generate controller from goals as is, where the assumptions are in OR"""
        controller_generated_or, trivial_or, exec_time_or = create_general_controller_from_goals(
            list_of_goals, result_folder + "/general_with_or/", "OR")
        ret = "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
        ret += "GENERAL SPECIFICATION WITH ALL GAOLS: **OR** OF ASSUMPTIONS **AND** OF GUARANTEES\n"
        ret += "-->\t" + str(len(list_of_goals)) + " goals: " + str(
            [c.name for c in list_of_goals]) + "\n"
        if controller_generated_and:
            ret += "REALIZABLE\tYES\t\t" + format(exec_time_or,
                                                  '.3f') + "sec\n"
        else:
            ret += "REALIZABLE\tNO\t\t" + format(exec_time_or, '.3f') + "sec\n"
        if trivial_and:
            ret += "TRIVIAL\tYES\t\t\n"
        else:
            ret += "TRIVIAL\tNO\t\t\n"
        ret += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
        f = open(summary_file_name, "a+")
        f.write(ret)
        f.close()

    if no_clusters:
        """No Clustering, Conjunction of all the goals (with saturated G = A->G)"""
        try:
            cgt = conjunction(deepcopy(list_of_goals))
        except CGTFailException as e:
            print(pretty_cgt_exception(e))
            sys.exit()
        save_to_file(str(cgt), result_folder + "/CGT_no_clusters/CGT.txt")
        save_to_file(str(cgt.print_cgt_CROME()),
                     result_folder + "/CGT_no_clusters/CGT_CROME.txt")
        """Generate a controller from cgt root"""
        realizable_no_clusters, no_clusters_exec_time = generate_controller_from_cgt(
            cgt, result_folder + "/CGT_no_clusters/", complete)

        ret = "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
        ret += "CGT WITH CONJUNCTION OF GOALS\n"
        ret += "-->\t" + str(len(list_of_goals)) + " goals: " + str(
            [c.name for c in list_of_goals]) + "\n"
        if realizable_no_clusters:
            ret += "REALIZABLE\tYES\t\t" + format(no_clusters_exec_time,
                                                  '.3f') + "sec\n"
        else:
            ret += "REALIZABLE\tNO\t\t" + format(no_clusters_exec_time,
                                                 '.3f') + "sec\n"
        ret += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
        f = open(summary_file_name, "a+")
        f.write(ret)
        f.close()
    """Clustering"""
    """Create cgt with the goals, it will automatically compose/conjoin them based on the context"""
    context_goals = create_contextual_clusters(list_of_goals, "MUTEX",
                                               rules["context"])

    if clusters_mutex:
        """Create the CGT composing the goals with the context"""
        try:
            cgt_1 = create_cgt(context_goals, compose_with_context=True)
        except CGTFailException as e:
            print(pretty_cgt_exception(e))
            sys.exit()
        save_to_file(str(cgt_1), result_folder + "/cgt_clusters_mutex/CGT.txt")
        save_to_file(str(cgt_1.print_cgt_CROME()),
                     result_folder + "/cgt_clusters_mutex/CGT_CROME.txt")
        """Generate a controller for each branch of the CGT"""
        realizables_clustered, exec_times_clustered = generate_controllers_from_cgt_clustered(
            cgt_1, result_folder + "/cgt_clusters_mutex/", complete)

        ret = "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
        ret += "CGT WITH MUTEX CLUSTERS \t  " + str(
            sum(realizables_clustered)) + "/" + str(
                len(realizables_clustered)) + " REALIZABLE \n"
        cluster_goals = cgt_1.refined_by
        ret += "FEASIBLE CLUSTERS:\t " + str(len(cluster_goals)) + "/" + str(
            len(context_goals.keys()))
        for i, goal in enumerate(cluster_goals):
            ret += "\nCLUSTER " + str(i) + "\n"
            ret += "SCENARIO:\t" + str(
                goal.goal_context_to_show.formula) + "\n-->\t" + str(
                    len(goal.refined_by)) + " goals: " + str(
                        [g.name for g in goal.refined_by]) + "\n"
            if len(realizables_clustered) > 0:
                if realizables_clustered[i]:
                    ret += "REALIZABLE\tMUTEX    \tYES\t\t" + format(
                        exec_times_clustered[i], '.3f') + "sec\n"
                else:
                    ret += "REALIZABLE\tMUTEX    \tNO\t\t" + format(
                        exec_times_clustered[i], '.3f') + "sec\n"
        ret += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"

        f = open(summary_file_name, "a+")
        f.write(ret)
        f.close()

    if clusters_origianl:
        """Create the CGT composing the goals without the context"""
        try:
            cgt_2 = create_cgt(context_goals, compose_with_context=False)
        except CGTFailException as e:
            print(pretty_cgt_exception(e))
            sys.exit()

        save_to_file(str(cgt_2), result_folder + "/CGT_with_clusters/CGT.txt")
        save_to_file(str(cgt_2.print_cgt_CROME()),
                     result_folder + "/CGT_with_clusters/CGT_CROME.txt")

        realizables_original, exec_times_original = generate_controllers_from_cgt_clustered(
            cgt_2, result_folder + "/CGT_with_clusters/", complete)

        unrealizable_goals = {}

        ret = "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
        ret += "CGT WITH CLUSTERS \t" + str(
            sum(realizables_original)) + "/" + str(
                len(realizables_original)) + " REALIZABLE\n"
        original_goals = cgt_2.refined_by
        ret += "FEASIBLE CLUSTERS:\t " + str(len(original_goals)) + "/" + str(
            len(context_goals.keys()))
        for i, goal in enumerate(original_goals):
            ret += "\nCLUSTER " + str(i) + "\n"
            ret += "SCENARIO:\t" + str(
                goal.goal_context_to_show.formula) + "\n-->\t" + str(
                    len(goal.refined_by)) + " goals: " + str(
                        [g.name for g in goal.refined_by]) + "\n"
            if len(realizables_original) > 0:
                if realizables_original[i]:
                    ret += "REALIZABLE \tYES\t\t" + format(
                        exec_times_original[i], '.3f') + "sec\n"
                else:
                    ret += "REALIZABLE \tNO\t\t" + format(
                        exec_times_original[i], '.3f') + "sec\n"
                    for g_name in [g.name for g in goal.refined_by]:
                        if g_name in unrealizable_goals.keys():
                            unrealizable_goals[g_name] += 1
                        else:
                            unrealizable_goals[g_name] = 1
        ret += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"

        ret += "\n~~~~~~~~~~'UNSAT-CORE' -  UNREALIZABLE GOALS~~~~~~~~~~~~~~~~\n"
        sorted_unrealizable_goals = sorted(unrealizable_goals.items(),
                                           key=lambda x: x[1],
                                           reverse=True)
        for (g, v) in sorted_unrealizable_goals:
            ret += g + "\t" + str(v) + "\n"
        ret += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
        f = open(summary_file_name, "a+")
        f.write(ret)
        f.close()

    # save_to_file(pretty_print_summary_clustering(list_of_goals,
    #                                              controller_generated_and,
    #                                              trivial_and,
    #                                              controller_generated_or,
    #                                              trivial_or,
    #                                              realizable_no_clusters,
    #                                              context_goals,
    #                                              realizables_clustered,
    #                                              realizables_original),
    #              result_folder + "/SUMMARY.txt")

    print("\nClustering process finished. Results generated.")

    return realizable_no_clusters, realizables_clustered, realizables_original, no_clusters_exec_time, exec_times_clustered, exec_times_original
Esempio n. 8
0
    for ctx, goals in context_goals.items():
        from helper.buchi import generate_buchi

        g_name = "||".join(g.name for g in goals)
        generate_buchi(ctx, file_path + "/buchi/" + g_name)

    # save_to_file(pretty_print_summary_clustering(context_goals), file_path + "/context-goals")

    try:
        cgt = create_cgt(context_goals, compose_with_context=False)
    except CGTFailException as e:
        print(pretty_cgt_exception(e))
        sys.exit()

    save_to_file(str(cgt), file_path + "/cgt_1_contexual")
    """Adding Domain Properties (i.e. descriptive statements about the problem world (such as physical laws)
    E.g. a robot cannot be in two locations at the same time. These properties are intrinsic in each pattern"""
    # cgt.add_domain_properties()

    save_to_file(str(cgt), file_path + "/cgt_2_domain")
    """Adding Domain Hypothesis or Expectations (i.e. prescriptive assumptions on the environment
    E.g. In the environment of deployment of the mission the item weight 10kg so in order to pick it up 
    there is a new assumption where the 'weight_power' must be at least 10"""
    expectations = [
        Contract(assumptions=Assumptions(
            Assumption(formula="G(weight_power > 10)",
                       variables=Variables(BoundedNat("weight_power")),
                       kind="expectation")),
                 guarantees=Guarantees(
                     Guarantee(formula="G(heavy_item_pickup)",