def Cpre_0(antichain, graph, nbr_functions, max_value):
    """
    Computes the antichain of the controllable predecessors for player 0 of 'antichain'.
    :param antichain:
    :type antichain:
    :param graph:
    :type graph:
    :param nbr_functions:
    :type nbr_functions:
    :param max_value:
    :type max_value:
    :return:
    :rtype:
    """

    if antichain.incomparable_elements == []:
        return antichain

    cur_antichain = Antichain(comparator_generalized_0,
                              intersector_generalized_0)
    for element in antichain.incomparable_elements:
        for pred in graph.get_predecessors(element[0]):
            if graph.get_node_player(pred) == 0:
                computed_down = down_generalized_0(element,
                                                   graph.nodes[pred][1:], pred,
                                                   nbr_functions, max_value)
                if computed_down != -1:
                    cur_antichain.insert(computed_down)

    return cur_antichain
Exemplo n.º 2
0
def Cpre_0(antichain, graph, max_counter):
    """
    Computes the antichain of the controllable predecessors for player 0 of 'antichain'.
    :param antichain:
    :type antichain:
    :param graph:
    :type graph:
    :param max_counter:
    :type max_counter:
    :return:
    :rtype:
    """

    if antichain.incomparable_elements == []:
        return antichain

    cur_antichain = Antichain(comparator, intersector)

    # check predecessors of each node present in the antichain
    for element in antichain.incomparable_elements:
        for pred in graph.get_predecessors(element[0]):

            # if said predecessors belong to player 0, compute down and add to the result
            if graph.get_node_player(pred) == 0:

                computed_down = down(element, graph.get_node_priority(pred),
                                     pred, max_counter)

                if computed_down != -1:
                    cur_antichain.insert(computed_down)

    return cur_antichain
Exemplo n.º 3
0
def create_start_antichain(starting_nodes, nbr_func, even_values):
    # TODO this is a crude creation adding every possibility, we can directly add the max elements io the max
    # even value for each
    start_antichain = Antichain(comparator_generalized, intersector_generalized)

    # create the antichain of maximal elements of the safe set
    # every counter in every tuple has the maximal value
    for node in starting_nodes:
        temp = [0] * (nbr_func + 1)
        temp[0] = node
        for func in range(1, nbr_func + 1):
            # even values are sorted
            temp[func] = even_values[func - 1][0] # even values are sorted so first is smallest
        start_antichain.insert(temp)

    return start_antichain
def Cpre_1(antichain, graph, nbr_functions, max_value):
    """
    Computes the antichain of the controllable predecessors for player 1 of 'antichain'.
    :param antichain:
    :type antichain:
    :param graph:
    :type graph:
    :param nbr_functions:
    :type nbr_functions:
    :param max_value:
    :type max_value:
    :return:
    :rtype:
    """

    if antichain.incomparable_elements == []:
        return antichain

    cur_antichain = Antichain(comparator_generalized_0,
                              intersector_generalized_0)
    for node in graph.get_nodes():
        if graph.get_node_player(node) == 1:
            first_iteration = True
            temp2 = Antichain(
                comparator_generalized_0,
                intersector_generalized_0)  # contains the set for intersection
            for succ in graph.get_successors(node):
                temp1 = Antichain(comparator_generalized_0,
                                  intersector_generalized_0)
                for element in antichain.incomparable_elements:
                    if element[0] == succ:

                        computed_down = down_generalized_0(
                            element, graph.nodes[node][1:], node,
                            nbr_functions, max_value)
                        # print("Down = "+str(computed_down)+" Compute down of "+str(element)+" with prio "+str(graph.get_node_priority(node))+" node "+str(node)+" val max "+str(max_counter))

                        if computed_down != -1:
                            temp1.insert(computed_down)

                if first_iteration:
                    temp2 = temp1
                    first_iteration = False
                else:
                    # print("temp1 "+str(temp1)+ " temp2 "+str(temp2))
                    temp2 = temp1.intersection(temp2)
                    # print("inter  "+str(temp2))

            cur_antichain = cur_antichain.union(temp2)

    return cur_antichain
def get_winning_regions_incremental(graph):
    """
    Incremental algorithm to obtain the solution of the generalized parity game from the solutions of the
    safety games with incrementally larger maximum values.
    :param graph:
    :type graph:
    :return:
    :rtype:
    """

    # start with small maximum value
    max_value = 1

    # the game is completely solved if we have decided a winner for each node
    completely_solved = False

    nbr_nodes = len(graph.get_nodes())
    while not completely_solved:

        # compute both fixpoints for the current maximal value
        fixpoint_0 = compute_fixpoint_0(graph, max_value)
        # TODO this shoould be fixpoint_1 = compute_fixpoint_p1(graph, max_value)
        fixpoint_1 = Antichain(comparator_generalized_0,
                               intersector_generalized_0)

        # extract both winning regions
        winning_region_0 = set()
        winning_region_1 = set()

        for element in fixpoint_0.incomparable_elements:
            winning_region_0.add(element[0])

        for element in fixpoint_1.incomparable_elements:
            winning_region_1.add(element[0])

        # check if the game is completely solved
        # TODO we need a stopping criterion when the theoretical maximal value that gives the equivalence is reached
        # TODO for testing purposes, stop at max_value = 100
        if len(winning_region_0) + len(
                winning_region_1) == nbr_nodes or max_value == 100:
            completely_solved = True

            # print("MAX VALUE "+str(max_value))
            # print("winning 0 " + str(winning_region_0))
            # print("winning 1 " + str(winning_region_1))

        # if it is not, increment the maximal value
        max_value += 1
        # print("value "+str(max_value)+" current fixpoint 0 : "+ str( fixpoint_0))
        # print("value "+str(max_value)+" current fixpoint 1 : "+ str( fixpoint_1))

    return list(winning_region_0), list(winning_region_1)
def compute_fixpoint_0(graph, max_value):
    """
    Computes the fixpoint obtained by the symbolic version of the backward algorithm for safety games.
    Starts from the antichain of the safe set and works backwards using controllable predecessors.
    The maximum value for the counters is a parameter to facilitate the incremental algorithm.
    :param graph:
    :type graph:
    :param max_value:
    :type max_value:
    :return:
    :rtype:
    """

    # wether we want to print the sets during computation
    toPrint = False

    # get the values to create the create the antichain of maximal elements of the safe set
    nbr_functions, nbr_counters_per_function = compute_counters_sizes_0(graph)

    start_antichain = Antichain(comparator_generalized_0,
                                intersector_generalized_0)

    # create the antichain of maximal elements of the safe set
    # every counter in every tuple has the maximal value
    for node in graph.get_nodes():
        temp = [node]
        for func in range(0, nbr_functions):
            temp.append(nbr_counters_per_function[func] * [max_value])
        start_antichain.insert(temp)

    if (toPrint):
        print("Start antichain : " + str(start_antichain) + "\n")

    antichain1 = start_antichain

    cpre1 = Cpre(start_antichain, 1, graph, nbr_functions, max_value)

    if (toPrint):
        print("CPre_1 of start antichain: " + str(cpre1) + "\n")

    cpre0 = Cpre(start_antichain, 0, graph, nbr_functions, max_value)

    if (toPrint):
        print("CPre_0 of start antichain: " + str(cpre0) + "\n")

    # we know the elements of cpre0 and cpre1 to be incomparable. Union of the two antichains can be done through
    # simple extend
    cpre0.incomparable_elements.extend(cpre1.incomparable_elements)

    if (toPrint):
        print("Union of CPre_0 and CPre_1 " + str(cpre0) + "\n")

    antichain2 = antichain1.intersection(cpre0)

    if (toPrint):
        print("Inter of start and previous union " + str(antichain2) + "\n")

    nb_iter = 0

    # while we have not obtained the fixpoint
    while not antichain1.compare(antichain2):

        nb_iter += 1

        antichain1 = antichain2

        cpre1 = Cpre(antichain1, 1, graph, nbr_functions, max_value)
        if (toPrint):
            print("ITER " + str(nb_iter) + " CPre 1 of prev " + str(cpre1) +
                  "\n")

        cpre0 = Cpre(antichain1, 0, graph, nbr_functions, max_value)

        if (toPrint):
            print("ITER " + str(nb_iter) + " CPre 0 of prev " + str(cpre0) +
                  "\n")

        temp = cpre0.union(cpre1)

        if (toPrint):
            print("ITER " + str(nb_iter) + " Union of Pre 0 and Pre 1  " +
                  str(temp) + "\n")

        antichain2 = antichain1.intersection(temp)

        if (toPrint):
            print("ITER " + str(nb_iter) + " final set  " + str(antichain2) +
                  "\n")

    return antichain1
Exemplo n.º 7
0
    def test_natvectors(self):
        print("Testing natural vector antichains")

        def compare_lists(t1, t2):
            return len(t1) == len(t2) and\
                all(map(lambda x: x[0] <= x[1], zip(t1, t2)))

        def meet_lists(t1, t2):
            assert len(t1) == len(t2)
            return map(lambda x: max(x[0], x[1]), zip(t1, t2))

        ac = Antichain(compare_lists, meet_lists)
        ac.insert([1, 2])  # this should enter
        self.assertTrue(ac.contains([1, 2]))
        ac.insert([1, 3])  # this is larger than the previous one
        self.assertFalse(ac.contains([1, 2]))
        self.assertTrue(ac.contains([1, 3]))
        ac.insert([2, 1])  # this should enter too
        self.assertTrue(ac.contains([2, 1]))
        self.assertTrue(ac.contains([1, 3]))
Exemplo n.º 8
0
def compute_fixpoint(graph):
    """
    Computes the fixpoint obtained by the symbolic version of the backward algorithm for safety games.
    Starts from the antichain of the safety set and works backwards using controllable predecessors.
    :param graph:
    :type graph:
    :return:
    :rtype:
    """

    # wether we want to print the sets during computation
    toPrint = False

    # create the antichain of maximal elements of the safe set
    max_counter = compute_max_counter(graph)
    start_antichain = Antichain(comparator, intersector)
    for node in graph.get_nodes():
        start_antichain.insert([node] + max_counter)

    if (toPrint):
        print("Start antichain : " + str(start_antichain) + "\n")

    antichain1 = start_antichain

    cpre1 = Cpre(start_antichain, 1, graph, max_counter)

    if (toPrint):
        print("CPre_1 of start antichain: " + str(cpre1) + "\n")

    cpre0 = Cpre(start_antichain, 0, graph, max_counter)

    if (toPrint):
        print("CPre_0 of start antichain: " + str(cpre0) + "\n")

    # we know the elements of cpre0 and cpre1 to be incomparable. Union of the two antichains can be done through
    # simple extend
    cpre0.incomparable_elements.extend(cpre1.incomparable_elements)

    if (toPrint):
        print("Union of CPre_0 and CPre_1 " + str(cpre0) + "\n")

    antichain2 = antichain1.intersection(cpre0)

    if (toPrint):
        print("Inter of start and previous union " + str(antichain2) + "\n")

    nb_iter = 0

    # while we have not obtained the fixpoint
    while not antichain1.compare(antichain2):

        nb_iter += 1

        antichain1 = antichain2

        cpre1 = Cpre(antichain1, 1, graph, max_counter)

        if (toPrint):
            print("ITER " + str(nb_iter) + " CPre 1 of prev " + str(cpre1) +
                  "\n")

        cpre0 = Cpre(antichain1, 0, graph, max_counter)

        if (toPrint):
            print("ITER " + str(nb_iter) + " CPre 0 of prev " + str(cpre0) +
                  "\n")

        temp = cpre0.union(cpre1)

        if (toPrint):
            print("ITER " + str(nb_iter) + " Union of Pre 0 and Pre 1  " +
                  str(temp) + "\n")

        antichain2 = antichain1.intersection(temp)

        if (toPrint):
            print("ITER " + str(nb_iter) + " final set  " + str(antichain2) +
                  "\n")

    return antichain1
Exemplo n.º 9
0
def compute_fixpoint(graph, starting_nodes, nbr_func, even_values, max_values):
    """
    This is the attractor starting node is f_j
    Computes the fixpoint obtained by the symbolic version of the backward algorithm for safety games.
    Starts from the antichain of the safe set and works backwards using controllable predecessors.
    The maximum value for the counters is a parameter to facilitate the incremental algorithm.
    :param graph:
    :type graph:
    :param max_value:
    :type max_value:
    :return:
    :rtype:
    """

    if DEBUG_PRINT:
        print("ARRIVING IN FIXPOINT ")
        print(graph)
        print("even_values " + str(even_values))
        print("max values " + str(max_values))

    # wether we want to print the sets during computation
    toPrint = False

    # start antichain is antichain of tj
    start_antichain = create_start_antichain(starting_nodes, nbr_func, even_values)

    # TODO change intersection to union, also add target as union when computing cpre, also the true start is
    # the cpre of start

    if (toPrint):
        print("Dtart antichain  : " + str(start_antichain) + "\n")

    cpre1 = Cpre(start_antichain, 1, graph, nbr_func, max_values)

    if (toPrint):
        print("CPre_1 of start antichain - new start : " + str(cpre1) + "\n")

    cpre0 = Cpre(start_antichain, 0, graph, nbr_func, max_values)

    if (toPrint):
        print("CPre_0 of start antichain - new start : " + str(cpre0) + "\n")

    # we know the elements of cpre0 and cpre1 to be incomparable. Union of the two antichains can be done through
    # simple extend
    cpre0.incomparable_elements.extend(cpre1.incomparable_elements)

    if (toPrint):
        print("New start antichain : " + str(cpre0) + "\n")

    antichain1 = cpre0

    antichain1_union_start = Antichain(comparator_generalized, intersector_generalized)
    antichain1_union_start.union(cpre0)
    antichain1_union_start.union(start_antichain)

    cpre1 = Cpre(antichain1_union_start, 1, graph, nbr_func, max_values)

    if (toPrint):
        print("CPre_1 of start antichain: " + str(cpre1) + "\n")

    cpre0 = Cpre(antichain1_union_start, 0, graph, nbr_func, max_values)

    if (toPrint):
        print("CPre_0 of start antichain: " + str(cpre0) + "\n")

    # we know the elements of cpre0 and cpre1 to be incomparable. Union of the two antichains can be done through
    # simple extend
    cpre0.incomparable_elements.extend(cpre1.incomparable_elements)

    if (toPrint):
        print("Union of CPre_0 and CPre_1 " + str(cpre0) + "\n")

    tmp = copy.deepcopy(antichain1)
    antichain2 = antichain1.union(cpre0)
    antichain1 = tmp

    if (toPrint):
        print("Union of new start and previous union " + str(antichain2) + "\n")

    nb_iter = 0

    #print("antichain 1"+str(antichain1))
    #print("antichain 2" +str(antichain2))
    # while we have not obtained the fixpoint
    while not antichain2.compare(antichain1):

        nb_iter += 1

        antichain1 = antichain2

        antichain1_union_start = Antichain(comparator_generalized, intersector_generalized)
        antichain1_union_start.union(antichain1)
        antichain1_union_start.union(start_antichain)

        cpre1 = Cpre(antichain1_union_start, 1, graph, nbr_func, max_values)
        if (toPrint):
            print("ITER " + str(nb_iter) + " CPre 1 of prev " + str(cpre1) + "\n")

        cpre0 = Cpre(antichain1_union_start, 0, graph, nbr_func, max_values)

        if (toPrint):
            print("ITER " + str(nb_iter) + " CPre 0 of prev " + str(cpre0) + "\n")

        temp = cpre0.union(cpre1)

        if (toPrint):
            print("ITER " + str(nb_iter) + " Union of Pre 0 and Pre 1  " + str(temp) + "\n")

        tmp = copy.deepcopy(antichain1)
        antichain2 = antichain1.union(temp)
        antichain1 = tmp


        if (toPrint):
            print("ITER " + str(nb_iter) + " final set  " + str(antichain2) + "\n")

    return antichain1