Esempio n. 1
0
 def test_parse_params_from_model(self):
     print(colored('Parse parameters from a given model', 'blue'))
     self.assertEqual(parse_params_from_model(os.path.join(model_dir, "asynchronous_2.pm")), ([], ["p", "q"]))
                            data_set = load_data(os.path.join(
                                data_dir,
                                f"bee/multiparam/data_n={population_size}.csv"
                            ),
                                                 debug=debug)
                        else:
                            data_set = load_data(os.path.join(
                                data_dir,
                                f"bee/2-param/data_n={population_size}.csv"),
                                                 debug=debug)

                        ## SETUP PARAMETERS AND THEIR DOMAINS
                        if multiparam:
                            parameters = parse_params_from_model(os.path.join(
                                model_path,
                                f"bee/multiparam_semisynchronous_{population_size}_bees.pm"
                            ),
                                                                 silent=silent
                                                                 )[1]
                        else:
                            parameters = parse_params_from_model(os.path.join(
                                model_path,
                                f"bee/semisynchronous_{population_size}_bees.pm"
                            ),
                                                                 silent=silent
                                                                 )[1]
                        print("model parameters: ", parameters)

                        if debug:
                            print("parameters", parameters)
                        parameter_domains = []
                        for item in parameters:
Esempio n. 3
0
def call_prism_files(model_prefix, agents_quantities, param_intervals=False, seq=False, no_prob_checks=False, memory="",
                     model_path=model_path, properties_path=properties_path, property_file=False,
                     output_path=prism_results, gui=False, silent=False, coverage=0.95):
    """  Calls prism for each file matching the prefix.

    Args:
        model_prefix (string): file prefix to be matched
        agents_quantities (list of ints): pop_sizes to be used
        param_intervals (list of pairs or False): list of intervals to be used for respective parameter (default all intervals are from 0 to 1)
        seq (bool): if true it will take properties one by one and append the results (helps to deal with memory)
        no_prob_checks (bool or string): True if no noprobchecks option is to be used for prism
        model_path (string): path to load  models from
        properties_path (string): path to load properties from
        property_file (string): file name of single property files to be used for all models
        output_path (string): path for the output
        memory (string or int): sets maximum memory in GB, see https://www.prismmodelchecker.org/manual/ConfiguringPRISM/OtherOptions
        gui (function or False): callback function to be used
        silent (bool): if True the output is put to minimum
        coverage (float): if refinement, coverage is used to set up threshold
    """
    if no_prob_checks:
        no_prob_checks = '-noprobchecks '
    else:
        no_prob_checks = ""

    if memory == "":
        memory = ""
    elif "javamaxmem" not in str(memory):
        memory = f'-javamaxmem {memory}g '

    if not agents_quantities:
        # print("I was here")
        agents_quantities = [""]

    if len(agents_quantities) == 1 and os.path.isdir(os.path.dirname(output_path)):
        spam = output_path
        output_path = os.path.dirname(spam)
        output_file = os.path.basename(spam)
    else:
        output_file = False

    for N in sorted(agents_quantities):
        # print("glob.glob(os.path.join(model_path, model_prefix + str(N) + .pm))", glob.glob(os.path.join(model_path, model_prefix + str(N) + ".pm")))
        # print("glob.glob(os.path.join(model_path, model_prefix))", glob.glob(os.path.join(model_path, model_prefix)))
        # print("model_prefix", model_prefix)
        if "." in model_prefix:
            files = glob.glob(os.path.join(model_path, model_prefix))
        else:
            files = glob.glob(os.path.join(model_path, model_prefix + str(N) + ".pm"))
        if not silent:
            print("input files: ", files)
        if not files:
            print(colored("No model files for N="+str(N)+" found", "red"))
            if gui:
                gui(1, "Parameter synthesis", "No model files found.")
        for file in files:
            file = Path(file)
            start_time = time()

            ## Parsing the parameters from the files
            model_consts, model_parameters = parse_params_from_model(file, silent)
            params = ""
            i = 0
            for param in model_parameters:
                if param_intervals:
                    params = f"{params}{param}={param_intervals[i][0]}:{param_intervals[i][1]},"
                else:
                    params = f"{params}{param}=0:1,"
                i = i + 1
            ## Getting rid of the last ,
            if params:
                params = params[:-1]

            ## Calling the PRISM using our function
            if not property_file:
                call = f"{file} prop_{N}.pctl {memory}{no_prob_checks}"
                if model_parameters:
                    call = f"{call}-param {params}"
                output_file = f"{os.path.splitext(file)[0]}.txt"
                error = call_prism(call, seq=seq, model_path=model_path, properties_path=properties_path,
                                   std_output_file=os.path.join(output_path, output_file), silent=silent, coverage=coverage)
            elif len(agents_quantities) == 1:
                call = f"{file} {property_file} {memory}{no_prob_checks}"
                if model_parameters:
                    call = f"{call}-param {params}"
                error = call_prism(call, seq=seq, model_path=model_path, properties_path=properties_path,
                                   std_output_file=os.path.join(output_path, output_file), silent=silent, coverage=coverage)
            else:
                call = f"{file} {property_file} {memory}{no_prob_checks}"
                if model_parameters:
                    call = f"{call}-param {params}"
                error = call_prism(call, seq=seq, model_path=model_path, properties_path=properties_path,
                                   std_output_file=os.path.join(output_path, "{}_{}.txt".format(str(file.stem).split(".")[0], str(Path(property_file).stem).split(".")[0])),
                                   silent=silent, coverage=coverage)

            # print(f"  Return code is: {error}")
            if not silent:
                print(colored(f"  It took {socket.gethostname()}, {time() - start_time} seconds to run", "yellow"))

            if error[0] != 0:
                print(colored(f"While calling PRISM an error occurred", "yellow"))

            ## Check for missing files
            if error[0] == 404:
                print(colored(error[1], "red"))
                if gui:
                    gui(2, "Parameter synthesis", error[1])
                continue

            ## Check if memory problem has occurred
            if error[0] == "memory":
                if not seq:
                    ## A memory occurred while not seq, trying seq now
                    seq = True
                    ## Remove the file because appending would no overwrite the file
                    os.remove(os.path.join(output_path, "{}.txt".format(file.stem)))
                    print(colored("A memory error occurred. Running prop by prob now", "red"))
                    if gui:
                        gui(3, "Parameter synthesis", "A memory error occurred. Running prop by prob now")
                else:
                    ## A memory occurred while seq
                    ## Remove the file because appending would not overwrite the file
                    os.remove(os.path.join(output_path, "{}.txt".format(file.stem)))
                    memory = round(psutil.virtual_memory()[0] / 1024 / 1024 / 1024)  ## total memory converted to GB
                    if "wind" in system().lower():
                        previous_memory = set_java_heap_win(f"{memory}g")
                    print(colored(f"A memory error occurred while seq, max memory increased to {memory}GB", "red"))
                    if gui:
                        gui(3, "Parameter synthesis", f"A memory error occurred while seq, max memory increased to {memory}GB")

            if error[0] == "memory_fail":
                ## An error occurred even when seq and max memory, no reason to continue
                if gui:
                    gui(1, "Parameter synthesis", f"An error occurred even when seq and max memory")
                break

            ## Check if there was problem with sum of probabilities
            if error[0] == "noprobchecks":
                if no_prob_checks == "":
                    print(colored("Outgoing transitions checksum error occurred. Running with noprobchecks option", "red"))
                    no_prob_checks = '-noprobchecks '
                    if gui:
                        gui(3, "Parameter synthesis", "Outgoing transitions checksum error occurred. Running with noprobchecks option")
                else:
                    print(colored("This is embarrassing, but Outgoing transitions checksum error occurred while noprobchecks option", "red"))
                    if gui:
                        gui(2, "Parameter synthesis", "This is embarrassing, but Outgoing transitions checksum error occurred while noprobchecks option")

            ## Check for other errors
            if error[0] == "error":
                ## Check for NullPointerException
                if "NullPointerException" in error[1]:
                    if seq:
                        # print(colored(error[1], "red"))
                        print(colored("Sorry, I do not know to to fix this, please try it manually", "red"))
                        print()
                        if gui:
                            gui(1, "Parameter synthesis", "Sorry, I do not know to to fix this, please try it manually")
                        break
                    else:
                        print(colored("Trying to fix the null pointer exception by running prop by prop", "red"))
                        if gui:
                            gui(3, "Parameter synthesis", "Trying to fix the null pointer exception by running prop by prop")
                        seq = True
                        ## Remove the file because appending would no overwrite the file
                        os.remove(os.path.join(output_path, "{}.txt".format(file.stem)))
                elif ('OutOfMemoryError' in error[1]) or ("Cannot allocate memory" in error[1]):
                    if not seq:
                        seq = True
                    else:
                        print(colored(f"A memory error occurred while seq, close some programs and try again with more memory.", "red"))
                        if gui:
                            gui(2, "Parameter synthesis", f"A memory error occurred while seq, close some programs and try again with more memory.")
                elif "Type error" in error[1]:
                    print(colored("A type error occurred, please check input files or manual", "red"))
                    if gui:
                        gui(2, "Parameter synthesis", "A type error occurred, please check input files or manual")
                    continue
                elif "Syntax error" in error[1]:
                    print(colored("A syntax error occurred, please check input files or manual.", "red"))
                    if gui:
                        gui(2, "Parameter synthesis", "A syntax error occurred, please check input files or manual.")
                    continue
                else:
                    print("Unrecognised error occurred:")
                    print(colored(error[1], "red"))
                    if gui:
                        gui(1, "Parameter synthesis", f"Unrecognised error occurred: \n {error[1]}")
                    continue

            if error[0] != 0:
                ## If an error occurred call this function for this file again
                print()
                # print("seq",seq)
                # print("noprobchecks", noprobchecks)
                call_prism_files(model_prefix, [N], seq=seq, no_prob_checks=no_prob_checks, memory=memory, model_path=model_path,
                                 properties_path=properties_path, property_file=property_file, output_path=prism_results)
            print()

    ## Setting the previous memory on windows
    if "wind" in system().lower():
        try:
            set_java_heap_win(previous_memory)
        except UnboundLocalError:
            pass
Esempio n. 4
0
def generate_experiments_and_data(model_types,
                                  n_samples,
                                  populations,
                                  dimension_sample_size,
                                  sim_length=False,
                                  modular_param_space=None,
                                  input_folder=False,
                                  output_folder=False,
                                  silent=False,
                                  debug=False):
    """ Generate experiment data for given settings

    Args:
        model_types (list of strings): list of model types
        n_samples (list of ints): list of sample sizes
        populations (list of ints): list of agent populations
        dimension_sample_size (int): number of samples of in each parameter dimension to be used
        sim_length (int): length of the simulation
        modular_param_space (numpy array): parameter space to be used
        input_folder (str or path): folder where to search for models
        output_folder (str or path): folder to dump PRISM output
        silent (bool): if silent printed output is set to minimum
        debug (bool): if True extensive print will be used
    """
    max_sample = max(n_samples)
    start_time = time.time()

    if output_folder is False:
        output_folder = tmp

    i = 1
    experiments = {}
    data = {}
    for model_type in model_types:
        if not silent:
            print("model_type: ", model_type)
        data[model_type] = {}
        experiments[model_type] = {}
        for population_size in populations:
            if not silent:
                print("population size: ", population_size)
            if "semisyn" in model_type and not sim_length:
                sim_length = 3 * population_size
            elif "syn" in model_type and not sim_length:
                sim_length = 2 * population_size
            elif "asyn" in model_type and not sim_length:
                sim_length = 4 * population_size

            if input_folder is not False:
                model_path = input_folder
            model = os.path.join(
                model_path, (model_type + "_" + str(population_size) + ".pm"))
            if not os.path.isfile(model):
                model = os.path.join(
                    model_path,
                    (str(population_size) + "_" + model_type + ".pm"))
            if not os.path.isfile(model):
                model = os.path.join(
                    model_path,
                    (model_type + "_" + str(population_size) + ".pm"))
            if not os.path.isfile(model):
                model = os.path.join(
                    model_path,
                    (str(population_size) + "_bees_" + model_type + ".pm"))
            if not os.path.isfile(model):
                model = os.path.join(
                    model_path,
                    (model_type + "_" + str(population_size) + "_bees.pm"))
            if not os.path.isfile(model):
                model = os.path.join(
                    model_path,
                    (str(population_size) + "bees_" + model_type + ".pm"))
            if not os.path.isfile(model):
                model = os.path.join(
                    model_path,
                    (model_type + "_" + str(population_size) + "bees.pm"))
            if not os.path.isfile(model):
                raise Exception("Model file not found")

            # A bad way how to deal with model without N
            if isinstance(population_size, str):
                population_size = 0
            if not silent:
                print("model: ", model)

            consts, parameters = parse_params_from_model(model, silent=silent)
            if not silent:
                print("parameters: ", parameters)

            ## Modulate parameter space
            if modular_param_space is not None:
                param_space = modular_param_space
            else:
                param_space = numpy.random.random(
                    (len(parameters), dimension_sample_size))

            if not silent:
                print("parameter space: ")
                print(param_space)

            experiments[model_type][population_size] = {}
            data[model_type][population_size] = {}
            for n_sample in n_samples:
                experiments[model_type][population_size][n_sample] = {}
                data[model_type][population_size][n_sample] = {}

            # print(len(param_space[0]))
            for column in range(len(param_space[0])):
                column_values = []
                for value in param_space[:, column]:
                    column_values.append(value)
                column_values = tuple(column_values)
                if not silent:
                    print("parametrisation: ", column_values)
                for n_sample in n_samples:
                    experiments[model_type][population_size][n_sample][
                        column_values] = []
                    data[model_type][population_size][n_sample][
                        column_values] = []
                # file = open("path_{}_{}_{}_{}_{}.txt".format(model_type,N,max_sample,v_p,v_q),"w+")
                # file.close()
                for sample in range(1, max_sample + 1):
                    ## Dummy path file for prism output
                    parameter_values = ""
                    prism_parameter_values = ""

                    for value in range(len(parameters)):
                        parameter_values = parameter_values + "_" + str(
                            column_values[value])
                        prism_parameter_values = prism_parameter_values + str(
                            parameters[value]) + "=" + str(
                                column_values[value]) + ","
                    prism_parameter_values = prism_parameter_values[:-1]
                    # print(parameter_values)
                    # print(prism_parameter_values)

                    ## More profound path name here
                    ## path_file = f"path_{model_type}{N}_{max_sample}_{parameter_values}.txt"
                    path_file = os.path.join(
                        output_folder, "dump_file_{}_{}_{}_{}.txt".format(
                            model_type, population_size, max_sample,
                            str(time.time()).replace(".", "")))
                    # print(path_file)

                    ## Here is the PRISM called
                    if not silent:
                        print(
                            f"calling: \n {model} -const {prism_parameter_values} -simpath {str(sim_length)} {path_file}"
                        )
                    call_prism(
                        f"{model} -const {prism_parameter_values} -simpath {str(sim_length)} {path_file}",
                        silent=silent,
                        prism_output_path=os.path.join(
                            os.getcwd(), "results/prism_results"))

                    ## Parse the dump file
                    # print("curr dir:", os.getcwd())
                    with open(path_file, "rt") as file:
                        last_line = file.readlines()[-1]

                    ## Append the experiment
                    state = sum(
                        list(map(lambda x: int(x),
                                 last_line.split(" ")[2:-1])))

                    ## If some error occurred
                    ## A bad way how to deal with files without N
                    if population_size != 0:
                        if state > population_size or debug or "2" in last_line.split(
                                " ")[2:-1]:
                            print(last_line[:-1])
                            print("state: ", state)
                            print()
                        else:  ## If no error remove the file
                            os.remove(path_file)
                        for n_sample in n_samples:
                            if sample <= n_sample:
                                experiments[model_type][population_size][
                                    n_sample][column_values].append(state)
                for n_sample in n_samples:
                    ## A bad way how to deal with files without N
                    for i in range(population_size + 1):
                        data[model_type][population_size][n_sample][
                            column_values].append(
                                len(
                                    list(
                                        filter(
                                            lambda x: x == i,
                                            experiments[model_type]
                                            [population_size][n_sample]
                                            [column_values]))) / n_sample)
                print(
                    "states: ", experiments[model_type][population_size]
                    [max_sample][column_values])

    print(
        colored(
            f"  It took {socket.gethostname()} {time.time() - start_time} seconds to run",
            "yellow"))
    return experiments, data