예제 #1
0
def insert_stench_regle(gs: Gophersat, wumpus_voca: List, stench_voca: List):

    for stench in stench_voca:

        # Soit le symbole Wij
        ij = stench[1:]  # On enleve la lettre
        i = int(ij[:2])  # On prend les deux premiers chiffres pour l'indice i
        j = int(ij[2:])  # On prend les deux derniers chiffres pour l'indice j

        i_moins_1 = int_to_two_digits_str(i, -1)
        i_plus_1 = int_to_two_digits_str(i, 1)

        j_moins_1 = int_to_two_digits_str(j, -1)
        j_plus_1 = int_to_two_digits_str(j, 1)

        i = int_to_two_digits_str(i)
        j = int_to_two_digits_str(j)

        wumpuses = []

        if f"W{i_plus_1}{j}" in wumpus_voca:
            wumpuses.append(f"W{i_plus_1}{j}")

        if f"W{i_moins_1}{j}" in wumpus_voca:
            wumpuses.append(f"W{i_moins_1}{j}")

        if f"W{i}{j_plus_1}" in wumpus_voca:
            wumpuses.append(f"W{i}{j_plus_1}")

        if f"W{i}{j_moins_1}" in wumpus_voca:
            wumpuses.append(f"W{i}{j_moins_1}")

        clause = wumpuses + [f"-{stench}"]
        gs.push_pretty_clause(clause)
예제 #2
0
def push_clause_from_wumpus(gs: Gophersat,
                            case_contents: str,
                            position: Tuple[str, str],
                            is_from_know_method: bool = False,
                            enable_log: bool = False):

    if enable_log:
        print(f"contents is : {case_contents}")

    facts = []
    for case_content in case_contents:

        if enable_log:
            print(f"inserting from wumpus : {case_content}\n")

        tmp_facts = wumpus_to_clause(case_content, position)

        if tmp_facts == -1:
            print("Error : Invalid case contents : wumpus to clause")
            return -1
        else:
            facts = facts + tmp_facts

    if is_from_know_method == False:  # Si on utilise pas la methode know, on est certains de ce qu'il n'y a pas dans la case
        facts = facts + get_implicit_negative_facts(facts, position)

    for fact in facts:  # On doit inserer les clauses une a une
        gs.push_pretty_clause([fact])
예제 #3
0
def insert_trou_regle(gs: Gophersat, trou_voca: List, brise_voca: List):

    for trou in trou_voca:

        # Soit le symbole Tij, une chaine de caractere avec i et j appartient a [0..99]
        # On enleve la lettre et on recupere i et j
        ij = trou[1:]
        i = int(ij[:2])  # On prend les deux premiers chiffres pour l'indice i
        j = int(ij[2:])  # On prend les deux derniers chiffres pour l'indice j

        i_moins_1 = int_to_two_digits_str(i, -1)
        i_plus_1 = int_to_two_digits_str(i, 1)

        j_moins_1 = int_to_two_digits_str(j, -1)
        j_plus_1 = int_to_two_digits_str(j, 1)

        i = int_to_two_digits_str(i)
        j = int_to_two_digits_str(j)

        brises = []

        if f"B{i_plus_1}{j}" in brise_voca:
            brises.append(f"B{i_plus_1}{j}")

        if f"B{i_moins_1}{j}" in brise_voca:
            brises.append(f"B{i_moins_1}{j}")

        if f"B{i}{j_plus_1}" in brise_voca:
            brises.append(f"B{i}{j_plus_1}")

        if f"B{i}{j_moins_1}" in brise_voca:
            brises.append(f"B{i}{j_moins_1}")

        for brise in brises:
            gs.push_pretty_clause([f"-{trou}", brise])
예제 #4
0
def insert_wumpus_stench_regle(gs: Gophersat, wumpus_voca: List,
                               stench_voca: List):

    for wumpus in wumpus_voca:

        # Soit le symbole Tij
        ij = wumpus[1:]  # On enleve la lettre
        i = int(ij[:2])  # On prend les deux premiers chiffres pour l'indice i
        j = int(ij[2:])  # On prend les deux derniers chiffres pour l'indice j

        i_moins_1 = int_to_two_digits_str(i, -1)
        i_plus_1 = int_to_two_digits_str(i, 1)

        j_moins_1 = int_to_two_digits_str(j, -1)
        j_plus_1 = int_to_two_digits_str(j, 1)

        i = int_to_two_digits_str(i)
        j = int_to_two_digits_str(j)

        stenches = []

        if f"S{i_plus_1}{j}" in stench_voca:
            stenches.append(f"S{i_plus_1}{j}")

        if f"S{i_moins_1}{j}" in stench_voca:
            stenches.append(f"S{i_moins_1}{j}")

        if f"S{i}{j_plus_1}" in stench_voca:
            stenches.append(f"S{i}{j_plus_1}")

        if f"S{i}{j_moins_1}" in stench_voca:
            stenches.append(f"S{i}{j_moins_1}")

        for stench in stenches:
            gs.push_pretty_clause([f"-{wumpus}", stench])
def is_number_possible(gs: Gophersat, number_to_insert: int, i: int, j: int):
    gs.push_pretty_clause([f"{number_to_insert}_{i}_{j}"])
    solvable = gs.solve()

    if not solvable:
        gs.pop_clause()

    return solvable
예제 #6
0
def insert_only_one_wumpus_regle(gs: Gophersat, wumpus_voca: List):

    wumpus_voca2 = wumpus_voca.copy()
    for case in wumpus_voca:
        wumpus_voca2.remove(case)

        for c in wumpus_voca2:
            gs.push_pretty_clause([f"-{case}", f"-{c}"])

    gs.push_pretty_clause(wumpus_voca)
예제 #7
0
def insert_une_menace_par_case_regle(gs: Gophersat, wumpus_voca: List,
                                     trou_voca: List):

    trou_voca_pile = trou_voca.copy()
    wumpus_voca_pile = wumpus_voca.copy()

    for i in range(len(wumpus_voca)):

        trou = trou_voca_pile.pop()
        wumpus = wumpus_voca_pile.pop()
        gs.push_pretty_clause([f"-{wumpus}", f"-{trou}"])
        gs.push_pretty_clause([f"-{trou}", f"-{wumpus}"])
예제 #8
0
def initialisation(N, random = False):
    ww = WumpusWorld(N, random)
    voc = creationVoc(ww.get_n())
    gs = Gophersat(gophersat_exec, voc)

    #état des lieux 1: on ne sait rien
    knowledge = [[]] * N
    for i in range(N):
        knowledge[i] = [''] * N
        for j in range(N):
            ajoutClauseEmpty(gs, i, j)
            ajoutClausesBreeze(gs, i, j)
            ajoutClausesStench(gs, i, j)
            ajoutClausesWumpus(gs, i, j)
            ajoutClausesPuit(gs, i, j)
    #on probe l'unique case safe
    probe1=ww.probe(0, 0)
    knowledge[0][0] = probe1[1]
    if ('.' in probe1[1]): #la case est empty
        gs.push_pretty_clause(["E0_0"])

    if ('B' in probe1[1]): #la case est breeze
        gs.push_pretty_clause(["B0_0"])

    if ('S' in probe1[1]): #la case est stenchy
        gs.push_pretty_clause(["S0_0"])
    return(ww, gs, knowledge)
def initialisation(size, wwr):
    #ww = WumpusWorld(size, random)
    voc = creationVoc(size)
    gs = Gophersat(gophersat_exec, voc)

    #état des lieux 1: on ne sait rien
    knowledge = [[]] * size
    for i in range(size):
        knowledge[i] = [''] * size
        for j in range(size):
            ajoutClauseEmpty(gs, i, j)
            ajoutClausesBreeze(size, gs, i, j)
            ajoutClausesStench(size, gs, i, j)
            ajoutClausesWumpus(size, gs, i, j)
            ajoutClausesPuit(size, gs, i, j)
    #on probe l'unique case safe
    status, probe1, cost = wwr.probe(0, 0)
    knowledge[0][0] = probe1
    if ('.' in probe1):  #la case est empty
        gs.push_pretty_clause(["E0_0"])

    if ('B' in probe1):  #la case est breeze
        gs.push_pretty_clause(["B0_0"])

    if ('S' in probe1):  #la case est stenchy
        gs.push_pretty_clause(["S0_0"])
    return (gs, knowledge)
def insert_only_one_number_in_case(gs: Gophersat, voca: List):

    for case in voca:
        num_case = int(case.split('_')[0])
        i = case.split('_')[1]
        j = case.split('_')[2]

        ou_clause = [case]
        for number in range(
                1, 10
        ):  # non(1_i_j) OU non(2_i_j) ET non(1_i_j) OU non(3_i_j) ET ... ET non(1_i_j) OU non(9_i_j)
            if num_case != number:
                ou_clause.append(f"{number}_{i}_{j}")
                gs.push_pretty_clause([f"-{case}", f"-{number}_{i}_{j}"])

        gs.push_pretty_clause(ou_clause)
        ou_clause = []
def insert_one_value_in_row(gs: Gophersat, voca: List):

    for case in voca:
        num_case = case.split('_')[0]
        i = case.split('_')[1]
        j = int(case.split('_')[2])

        ou_clause = [case]
        for j_prime in range(
                0, 9
        ):  # non(1_i_j) OU non(1_i_0) ET non(1_i_j) OU non(1_i_1) ET ... ET non(1_i_j) OU non(1_i_8)
            if j != j_prime:
                ou_clause.append(f"{num_case}_{i}_{j_prime}")
                gs.push_pretty_clause(
                    [f"-{case}", f"-{num_case}_{i}_{j_prime}"])

        gs.push_pretty_clause(ou_clause)
        ou_clause = []
def insert_one_value_in_col(gs: Gophersat, voca: List):

    for case in voca:
        num_case = case.split('_')[0]
        i = int(case.split('_')[1])
        j = case.split('_')[2]

        ou_clause = [case]
        for i_prime in range(
                0, 9
        ):  # non(1_i_j) OU non(1_1_j) ET non(1_i_j) OU non(1_2_j) ET ... ET non(1_i_j) OU non(1_8_j)
            if i != i_prime:
                ou_clause.append(f"{num_case}_{i_prime}_{j}")
                gs.push_pretty_clause(
                    [f"-{case}", f"-{num_case}_{i_prime}_{j}"])

        gs.push_pretty_clause(ou_clause)
        ou_clause = []
def insert_one_value_in_square(gs: Gophersat, voca: List):
    for case in voca:
        num_case = case.split('_')[0]
        i = int(case.split('_')[1])
        j = int(case.split('_')[2])

        ib = 3 * (i // 3)  # coordinates of the first case of the square
        jb = 3 * (j // 3)

        ou_clause = [case]
        for i_prime in range(ib, ib + 3):
            for j_prime in range(jb, jb + 3):
                if i != i_prime or j != j_prime:

                    ou_clause.append(f"{num_case}_{i_prime}_{j_prime}")
                    gs.push_pretty_clause(
                        [f"-{case}", f"-{num_case}_{i_prime}_{j_prime}"])

        gs.push_pretty_clause(ou_clause)
        ou_clause = []
def generate_sudoku() -> Tuple[List, List]:

    voc = generate_voca()
    gs = Gophersat(gophersat_exec, voc)

    insert_rules(gs, voc)

    soluce = generate_random_sudoku(gs)
    hidden_sudoku = hide_case_sudoku(0, soluce, gs)

    return (soluce, hidden_sudoku)
def hide_case_sudoku(difficulty: int, sudoku: List, gs: Gophersat):

    cpt = 0
    already_visited = []
    hidden_sudoku = copy.deepcopy(sudoku)

    while cpt < 15:

        i = random.randrange(0, 9)  # On chope des coordonnées au hasard
        j = random.randrange(0, 9)

        if (i, j) not in already_visited:

            gs.remove_pretty_clause([f"{sudoku[i][j]}_{i}_{j}"])
            gs.solve()

            hidden_sudoku[i][j] = ' '
            already_visited.append((i, j))
            cpt += 1

    if not is_there_one_model(gs):
        print(f"Error : more than one model : {gs.count_model()}")
    else:
        return hidden_sudoku
예제 #16
0
def cartographier(wwr: WumpusWorldRemote,
                  taille_grille: int = 4,
                  enable_log: bool = False):

    wumpus_voca = generate_wumpus_voca(taille_grille)
    gold_voca = generate_gold_voca(taille_grille)
    stench_voca = generate_stench_voca(taille_grille)
    brise_voca = generate_brise_voca(taille_grille)
    trou_voca = generate_trou_voca(taille_grille)

    voc = wumpus_voca + gold_voca + stench_voca + brise_voca + trou_voca

    gs = Gophersat(gophersat_exec, voc)

    res = init_res(taille_grille)

    # On modelise les regles
    insert_all_regles(gs, wumpus_voca, trou_voca, brise_voca, stench_voca)

    if (gs.solve() and enable_log):
        print(f"vocabulaire inseré sans contradiction")
        print(wwr)
    elif (gs.solve() == False):
        print(f"contradiction dans le vocabulaire inseré")
        return -1

    if (enable_log):
        print("\nBefore loop log :\n")
        print(f"{gs.solve()}")
        print(f"{gs.get_pretty_model()}")
        print("\n==========================\n")

    i_str = ""
    j_str = ""

    status, percepts, cost = wwr.probe(0, 0)
    print(status, percepts, cost)
    res[0][0] = percepts
    is_from_know_method = False
    push_clause_from_wumpus(gs, percepts, ["00", "00"], is_from_know_method,
                            False)

    for i in range(taille_grille):
        for j in range(taille_grille):
            if i != 0 or j != 0:

                i_str = int_to_two_digits_str(i)
                j_str = int_to_two_digits_str(j)

                if is_wumpus_possible(gs, [i_str, j_str]):
                    if is_wumpus_mandatory(gs, [i_str, j_str], wumpus_voca):

                        status, percepts, cost = wwr.know_wumpus(i, j)
                        if percepts == "Correct wumpus position.":
                            percepts = "W"
                            is_from_know_method = True

                    else:
                        status, percepts, cost = wwr.cautious_probe(i, j)

                elif is_trou_possible(gs, [i_str, j_str]):
                    if is_trou_mandatory(gs, [i_str, j_str], trou_voca, res,
                                         taille_grille):

                        status, percepts, cost = wwr.know_pit(i, j)
                        if percepts == "Correct pit position.":
                            percepts = "P"
                            is_from_know_method = True

                    else:
                        status, percepts, cost = wwr.cautious_probe(i, j)

                else:
                    status, percepts, cost = wwr.probe(i, j)

                if enable_log:
                    print(status, percepts, cost, i, j)

                res[i][j] = percepts

                if (
                        push_clause_from_wumpus(gs, percepts, [i_str, j_str],
                                                is_from_know_method,
                                                False) == -1
                ):  # Si erreur lors de l'insertion de clauses on arrete tout : on fausse le modele
                    gs.solve()
                    print(f"Modele :\n {gs.get_pretty_model()} \n ---")
                    return -1

                is_from_know_method = False

                if (enable_log):
                    print_case_contents_post_insertion(i, j, percepts, wwr,
                                                       gs.solve())

    if (gs.solve() == False):
        return -1

    if (enable_log):
        print("\n\n==========================")

        print(f"Satisfiabilité : {gs.solve()}")
        print(f"Modele trouvé :\n {gs.get_pretty_model()} \n ---")

    return res
예제 #17
0
def insert_safety_regle(gs: Gophersat):

    gs.push_pretty_clause(["-W0000"])
    gs.push_pretty_clause(["-T0000"])
예제 #18
0
def insert_brise_regle(gs: Gophersat, brise_voca: List, trou_voca: List):

    #-Bij ou T(i-1)j ou T(i+1)j ou Ti(j-1) ou Ti(j+1)
    for brise in brise_voca:

        # Soit le symbole Bij
        # On enleve la lettre et on recupere i et j
        ij = brise[1:]
        i = int(ij[:2])  # On prend les deux premiers chiffres pour l'indice i
        j = int(ij[2:])  # On prend les deux derniers chiffres pour l'indice j

        i_moins_1 = int_to_two_digits_str(i, -1)
        i_plus_1 = int_to_two_digits_str(i, 1)

        j_moins_1 = int_to_two_digits_str(j, -1)
        j_plus_1 = int_to_two_digits_str(j, 1)

        i = int_to_two_digits_str(i)
        j = int_to_two_digits_str(j)

        trous = []

        if f"T{i_plus_1}{j}" in trou_voca:
            trous.append(f"T{i_plus_1}{j}")

        if f"T{i_moins_1}{j}" in trou_voca:
            trous.append(f"T{i_moins_1}{j}")

        if f"T{i}{j_plus_1}" in trou_voca:
            trous.append(f"T{i}{j_plus_1}")

        if f"T{i}{j_moins_1}" in trou_voca:
            trous.append(f"T{i}{j_moins_1}")

        clause = trous + [f"-{brise}"]
        gs.push_pretty_clause(clause)

    # -Tij ou B(i-1)j ou B(i+1)j ou Bi(j-1) ou Bi(j+1)
    for trou in trou_voca:

        # Soit le symbole Tij
        ij = trou[1:]  # On eneleve la lettre
        i = int(ij[:2])  # On prend les deux premiers chiffres pour l'indice i
        j = int(ij[2:])  # On prend les deux derniers chiffres pour l'indice j

        i_moins_1 = int_to_two_digits_str(i, -1)
        i_plus_1 = int_to_two_digits_str(i, 1)

        j_moins_1 = int_to_two_digits_str(j, -1)
        j_plus_1 = int_to_two_digits_str(j, 1)

        i = int_to_two_digits_str(i)
        j = int_to_two_digits_str(j)

        brises = []

        if f"B{i_plus_1}{j}" in brise_voca:
            brises.append(f"B{i_plus_1}{j}")

        if f"B{i_moins_1}{j}" in brise_voca:
            brises.append(f"B{i_moins_1}{j}")

        if f"B{i}{j_plus_1}" in brise_voca:
            brises.append(f"B{i}{j_plus_1}")

        if f"B{i}{j_moins_1}" in brise_voca:
            brises.append(f"B{i}{j_moins_1}")

        clause = brises + [f"-{trou}"]
        gs.push_pretty_clause(clause)
def is_there_one_model(gs: Gophersat):
    return gs.count_model() == 1