Exemple #1
0
def choose_auto_vis():
    """Presents a menu for the user to select if they wish to automatically
    visualize their automata upon import/creation.

    Returns
    -------
    bool
        Whether the setting was turned on, off, or neither (None)
    """
    display_menu(menu_msg)
    while True:
        inpt = input()
        # Check if the user wishes to quit
        inpt = inpt.lower()
        if inpt in ["y", "yes"]:
            global_settings.update(menu_option, True)
            show_notification("Auto-visualization turned on")
            return True
        elif inpt in ["n", "no"]:
            global_settings.update(menu_option, False)
            show_notification("Auto-visualization turned off")
            return False
        elif inpt in ["e", "exit"]:
            return None
        else:
            show_error("Command not recognized")
Exemple #2
0
def choose_gv_file_type():
    """Presents a menu for the user to select their desired graphviz file output
    type (pdf, png, jpeg...)

    Returns
    -------
    int
        The selected index, or None if quit
    """
    display_menu(menu_msg + get_file_type_options() + menu_msg_2)
    while True:
        inpt = input()
        try:
            # If we get a good number, select it!
            if int(inpt) in range(len(file_types)):
                selected = file_types[int(inpt)]
                show_notification("Selected:\n" + selected)
                global_settings.update(menu_option, selected)
                return int(inpt)
            else:
                show_error("Not a valid observer index")
        except ValueError:
            # Check if the user wishes to quit
            inpt = inpt.lower()
            if inpt in ["e", "exit"]:
                return None
            else:
                show_error("Command not recognized")
Exemple #3
0
def select_heuristic():
    """Opens a menu to select a heuristic for composing systems in a modular
    architecture to speed up operations.

    Parameters
    ----------
    None

    Returns
    -------
    None
    """
    display_menu(menu_msg)

    inpt = input()
    while (True):
        if inpt in ["0"]:
            show_notification("Selected no heuristic")
            return no_heuristic
        elif inpt in ["1"]:
            show_notification("Selected most shared events")
            return most_shared_heuristic
        elif inpt in ["2"]:
            show_notification("Selected least new events")
            return least_new_heuristic
        else:
            show_error("Command not recognized")
            inpt = input()
Exemple #4
0
def initialize():
    """Initializes the program's settings

    Returns
    -------
    None
    """
    global settings
    settings = defaults
    try:
        try:
            with open(settings_file, 'r') as f:
                # Load in the settings
                settings = json.load(f)

        except FileNotFoundError:
            with open(settings_file, 'w') as f:
                # Write new settings
                settings = defaults
                json.dump(settings, f)
    except Exception:
        show_error("Error reading/writing settings file.\n" +
                   "Reverting to defaults...")

    for k, v in defaults.items():
        if k not in settings:
            settings[k] = v
Exemple #5
0
def name_automaton_menu(automata, automaton):
    """Gives the user the opportunity to name an automaton, if the automaton
    is currently unnamed (or has a name that conflicts with another automaton
    already loaded).

    Parameters
    ----------
    automata : list
        The automata that are currently open (excluding the current automaton)
    automaton : dict
        The automaton to name (not in the list parameter)

    Returns
    -------
    None
    """
    bad_names = set([a["name"] for a in automata])
    bad_names.add("")

    # Checks if automaton already has a valid name; if so, done
    if "name" in automaton:
        if automaton["name"] not in bad_names:
            show_notification("Imported automaton " + automaton["name"])
            return

    # Otherwise, shows a menu to request a name
    display_menu(menu_msg)
    name = input()
    while name in bad_names:
        show_error("Name already taken! Try again")
        name = input()

    # Name the automaton and notify the user
    automaton["name"] = name
    show_notification("Imported automaton " + automaton["name"])
Exemple #6
0
def save(automaton):
    """Saves an automaton to a user-defined location in JSON form, dot form, and
    the GraphViz PDF form.

    Parameters
    ----------
    automaton : dict
        The automaton to save

    Returns
    -------
    None
    """
    show_notification("Select a location to save " + automaton["name"])
    location = filedialog.asksaveasfilename(title="Automaton Export Filename",
                                            defaultextension="json")
    # If selected a location, save it
    if len(location) == 0:
        show_error("No location given")
        return False
    else:
        with open(location, 'w') as f:  # writing JSON object
            dump(automaton, f, sort_keys=True, indent=4)

        # Remove the .json extension
        location = location[:-5]
        visualize(automaton, location, view=False)
        show_notification("Saved to " + location)
        return True
Exemple #7
0
def select_automata_menu(automata, min_selection=1, menu_name=None):
    """Menu for selecting multiple automata.

    Parameters
    ----------
    automata : list
        All automata that are available for selection
    min_selection : int
        The minimum number of automata needed
    menu_name : str
        The name for the menu

    Returns
    -------
    lst
        The automata that have been selected (or None if none selected)
    """
    if menu_name is None:
        menu_name = "Select Multiple Automata Menu"
    else:
        menu_name = "Select Automata for " + menu_name

    # Show the menu
    display_menu(menu_name + multiple_menu_msg)
    num_options = len(automata)
    selected = [False] * num_options

    # Keep selecting until type "e" or "exit"
    while True:
        print_selected(automata, selected)
        inpt = input()
        try:
            # Get the integer input from the user and select it
            if int(inpt) in range(num_options):
                inpt = int(inpt)
                selected[inpt] = not selected[inpt]
        except ValueError:
            # Check if we are done
            inpt = inpt.lower()
            if inpt in ["e", "exit"]:
                return None
            elif inpt in ["s", "save"]:
                result = [
                    automata[i] for i in range(num_options) if selected[i]
                ]
                if len(result) >= min_selection:
                    sel = [item["name"] for item in result]
                    show_notification("Selected:\n" + str(sel))
                    return result
                else:
                    # Prevent exit because selection was inadequate
                    show_error("At least " + str(min_selection) +
                               " automata must be selected")
            else:
                show_error("Command not recognized")
Exemple #8
0
def select_automaton_menu(automata, menu_name=None):
    """Menu for selecting a single automaton.

    Parameters
    ----------
    automata : list
        All automata that are available for selection
    menu_name : str
        The name for the menu

    Returns
    -------
    dict
        The automaton selected (or None if none selected)
    """
    if menu_name is None:
        menu_name = "Select Single Automaton Menu"
    else:
        menu_name = "Select Automaton for " + menu_name

    # Display the menu
    display_menu(menu_name + single_menu_msg)
    num_options = len(automata)
    selected = [False] * num_options

    # Keep selecting until type "e" or "exit"
    while True:
        print_selected(automata, selected)
        inpt = input()
        try:
            # If successfully selected, return the selection
            if int(inpt) in range(num_options):
                show_notification("Selected:\n" +
                                  str(automata[int(inpt)]["name"]))
                return automata[int(inpt)]
            else:
                show_error("Index not valid, max index is " +
                           str(num_options - 1))
        except ValueError:
            # See if the user wanted to exit
            inpt = inpt.lower()
            if inpt in ["e", "exit"]:
                return None
            else:
                show_error("Command not recognized")
Exemple #9
0
def main_menu(next_screens, automata, temp_dir):
    """Main menu for the application with all of the actions that are possible
    in the application at a high level.

    Parameters
    ----------
    next_screens : list
        The next screens that will be shown (a stack). This is not used much
        with the current version of the application, but it might be used in
        the future
    automata : list
        List of all automata loaded into the program
    temp_dir : str
        The string representing the temporary directory for files

    Returns
    -------
    None
    """
    display_menu(menu_msg)

    # Based on input, choose which type of operation to perform
    inpt = input().lower()
    if inpt in ["o", "open"]:
        open_file_menu(automata, temp_dir)
    elif inpt in ["l", "list"]:
        print_selected(automata)
        sleep(0.2)
    elif inpt in ["b", "begin"]:
        ops_menu(automata, temp_dir)
    elif inpt in ["s", "save"]:
        select_and_save(automata)
    elif inpt in ["c", "close"]:
        close_automata_menu(automata)
    elif inpt in ["v", "visualize"]:
        select_and_save_temp(automata, temp_dir)
    elif inpt in ["d", "settings"]:
        settings_menu()
    elif inpt in ["e", "exit"]:
        print("Exiting...")
        next_screens.pop()  # Remove main menu from the stack
    else:
        show_error("Command not recognized")
Exemple #10
0
def select_observer_menu(automaton):
    """Allows the user to select which observer to use for an operation (each
    observer has an observable alphabet, a controllable alphabet, and a set of
    secret states).

    Parameters
    ----------
    automaton : dict

    Returns
    -------
    int
        The index of the observer which has been selected
    """
    num_obs = len(automaton["events"]["observable"])
    max_input = str(num_obs - 1)

    # Create the menu message
    msg = menu_msg + max_input + menu_msg_2
    if num_obs > 1:
        msg += "1 through " + max_input + " are agents"
    msg += menu_msg_3

    # Display the message
    display_menu(msg)

    while True:
        inpt = input()
        try:
            # If we get a good number, select it!
            if int(inpt) in range(num_obs):
                show_notification("Selected:\n" + inpt)
                return int(inpt)
            else:
                show_error("Not a valid observer index")
        except ValueError:
            # Check if the user wishes to quit
            inpt = inpt.lower()
            if inpt in ["e", "exit"]:
                return None
            else:
                show_error("Command not recognized")
Exemple #11
0
def settings_menu():
    """Opens a menu with options for different settings which can be edited. It
    changes the default for all future sessions as well.

    Returns
    -------
    None
    """
    display_menu(menu_msg)

    inpt = input().lower()

    # Choose which operation to perform
    if inpt in ["f", "file"]:
        choose_gv_file_type()
    elif inpt in ["a"]:
        choose_auto_vis()
    elif inpt in ["e", "exit"]:
        pass
    else:
        show_error("Command not recognized")
Exemple #12
0
def update(setting, value):
    """Updates the setting with a new value

    Parameters
    ----------
    setting : str
        The setting to change
    value : any
        The new value for the setting

    Returns
    -------
    None
    """
    settings[setting] = value
    try:
        with open(settings_file, 'w') as f:
            # Write new settings
            json.dump(settings, f)
    except FileNotFoundError:
        show_error("Error writing settings file.\n" +
                   "Changes are only saved for this session.")
Exemple #13
0
def close_automata_menu(automata):
    """Menu for closing automaton. It has three major tasks: 1) selecting the
    automata, then 2) closing without saving or 3) closing with saving.
    When an automaton has been "closed", it is no longer in the automata list.
    If it has also been saved, the json and pdf are saved to disk.

    Parameters
    ----------
    automata : list
        List of all automata which are available to choose

    Returns
    -------
    None
    """
    display_menu(menu_msg)

    num_options = len(automata)
    selected = [False] * num_options

    # Keep on selecting automata to close until choose to stop
    while True:

        # Print what we've selected so far
        print_selected(automata, selected)
        inpt = input()
        try:
            # If input is fine, toggle the selection
            if int(inpt) in range(num_options):
                inpt = int(inpt)
                selected[inpt] = not selected[inpt]
        except ValueError:
            # Else, see if we want to exit, close, or save
            inpt = inpt.lower()
            if inpt in ["e", "exit"]:
                return None # Exit without closing
            elif inpt in ["c", "close"]:

                # Close all automata selected
                result = [automata[i] for i in range(num_options) if
                          selected[i]]
                for item in result:
                    automata.remove(item)
                sel = [item["name"] for item in result]
                show_notification("The following were closed:\n" + str(sel))
                return
            elif inpt in ["s", "save"]:

                # Save all automata selected and close all those not failed
                result = [automata[i] for i in range(num_options) if
                          selected[i]]

                # Keep track of those that fail to save, and don't close them
                failed = []
                for item in result:
                    saved = save(item)
                    if saved:
                        automata.remove(item)
                    else:
                        show_error("Could not save, so automaton not closed")
                        failed.append(item)

                # Show which ones were actually closed
                sel = [item["name"] for item in result if item not in failed]
                show_notification("The following were saved and closed:\n" + str(sel))
            else:
                show_error("Command not recognized")
Exemple #14
0
def ops_menu(automata, temp_dir):
    """Opens a menu with options for different operations that can be performed.

    Parameters
    ----------
    automata : list
        The list of automata currently open in the program
    temp_dir : str
        The temporary directory for the session

    Returns
    -------
    None
    """
    display_menu(menu_msg)

    inpt = input().lower()

    # Choose which operation to perform
    if inpt in ["d", "determinization"]:
        selected = select_automaton_menu(automata, "Determinization")
        if selected is not None:
            observer = select_observer_menu(selected)
            if observer is not None:
                result = determinize(selected, observer)
                __save(automata, result, temp_dir)
    elif inpt in ["o", "opacity"]:
        selected = select_automaton_menu(automata, "Checking Opacity")
        if selected is not None:
            observer = select_observer_menu(selected)
            if observer is not None:
                result = check_opacity(selected, observer)
                print("With respect to the observer " + str(observer) +
                      ", the system is opaque")
                print("for the following secrets:")
                print([i for i, x in enumerate(result) if x is True])
                print("The system is not opaque for the following secrets:")
                print([i for i, x in enumerate(result) if x is False])
    elif inpt in ["u", "union", "parallel composition"]:
        selected = select_automata_menu(automata, 2, "Parallel Composition")
        if selected is not None:
            result = union(selected)
            __save(automata, result, temp_dir)
    elif inpt in ["p", "product", "intersection"]:
        selected = select_automata_menu(automata, 2, "Intersection")
        if selected is not None:
            result = product(selected)
            __save(automata, result, temp_dir)
    elif inpt in ["a", "accessible"]:
        selected = select_automaton_menu(automata, "Accessibility Operation")
        if selected is not None:
            result = get_accessible(selected)
            __save(automata, result, temp_dir)
    elif inpt in ["c", "controllable"]:
        selected = select_automaton_menu(automata, "Controllability Operation")
        if selected is not None:
            result = get_controllable(selected)
            __save(automata, result, temp_dir)
    elif inpt in ["ca", "coaccessible"]:
        selected = select_automaton_menu(automata, "Coaccessibility Operation")
        if selected is not None:
            result = get_coaccessible(selected)
            __save(automata, result, temp_dir)
    elif inpt in ["l", "leakage"]:
        selected = select_automaton_menu(automata, "Get Leakage Automaton")
        if selected is not None:
            observer = select_observer_menu(selected)
            if observer is not None:
                secret = select_secret_menu(selected)
                if secret is not None:
                    result = create_leakage_automaton(selected, observer,
                                                      secret)
                    __save(automata, result, temp_dir)
    elif inpt in ["ba"]:
        selected = select_automaton_menu(automata, "Constructing Arena")
        if selected is not None:
            result = construct_arena(selected)
            __save(automata, result, temp_dir)
            show_notification("Bad states:\n" + str(result["states"]["bad"]))
    elif inpt in ["bt"]:
        selected = select_automaton_menu(automata, "Constructing Attractor")
        if selected is not None:
            result = construct_attractor(selected)
            __save(automata, result, temp_dir)
            show_notification("Bad states:\n" + str(result["states"]["bad"]))
    elif inpt in ["bp"]:
        selected = select_automaton_menu(automata, "Pruning Arena")
        if selected is not None:
            result = get_controllable(construct_attractor(selected))
            __save(automata, result, temp_dir)
    elif inpt in ["om"]:
        show_notification(
            "With this operation, we assume the\nattacker can see all items in the\nshared alphabet,as per Enforcing\nOpacity in Modular Systems (2020)"
        )
        selected = select_automata_menu(
            automata, 1, "Checking Opacity for Modular Systems")
        if selected is not None:
            heuristic = select_heuristic()
            result = check_modular_opacity(selected, heuristic=heuristic)
            show_notification("The modular system is " +
                              ("opaque" if result else "not opaque"))
    elif inpt in ["bca"]:
        selected = select_automaton_menu(automata,
                                         "Constructing Communication Arena")
        if selected is not None:
            result = construct_communication_arena(selected)
            __save(automata, result, temp_dir)
    elif inpt in ["e", "exit"]:
        pass
    else:
        show_error("Command not recognized")