コード例 #1
0
def graph_coloring2sat(G, k):
    # G[0] naj bo stevilo povezav
    # G[1] naj bo seznam parov vozlics, a.k.a, seznan pobexzav
    # k > 0 je stevilo barv
    assert k > 0, "Premalo barv"

    l = []

    # vsako vozlisce ima vsaj eno barvo
    l.append(
        prop.And([
            prop.Or(["v%dc%d" % (i, j) for j in range(k)]) for i in range(G[0])
        ]))
    # pari krajisc so razlicnih barv
    for (u, v) in G[1]:
        l.append(
            prop.And([
                prop.And([
                    prop.Not(
                        prop.And([
                            "v" + str(u) + "c" + str(c),
                            "v" + str(v) + "c" + str(c)
                        ])) for c in range(k)
                ])
            ]))
    # vsako vozlisce je kvecjemu ene barve
    for v in range(G[0]):
        for i in range(k):
            for j in range(i + 1, k):
                l.append(
                    prop.Not(
                        prop.And([
                            "v" + str(v) + "c" + str(i),
                            "v" + str(v) + "c" + str(j)
                        ])))
    phi = prop.And(l)
    #print phi
    return phi
コード例 #2
0
def hadamard2sat(n):
    assert n % 2 == 0
    l = []

    #naredi matrikco za lazje mislit
    ma3ka = {}
    for i in range(n):
        for j in range(n):
            ma3ka[(i, j)] = "v" + str(j) + "s" + str(i)
            #vjsi = vrstica j, stolpec i
    print ma3ka

    xOri = []
    #nardimo xOre vrstic za vsak stolpec.
    for i in range(n - 1):
        for j in range(n):
            xOri.append(
                prop.Or([
                    prop.And([ma3ka[(i, j)],
                              prop.Not(ma3ka[(i + 1, j)])]),
                    prop.And([prop.Not(ma3ka[(i, j)]), ma3ka[(i + 1, j)]])
                ]))
        #vse mozne true - false kombinacije
        a = list(itertools.combinations(xOri,
                                        len(xOri) / 2))

        #generiramo mozne stolpce
        stolpec = []
        for j in range(len(a)):
            stolpec.append(
                prop.And([x if x in a[j] else prop.Not(x) for x in xOri]))

        #nardimo or moznih stolpcev
        l.append(prop.Or(stolpec))
        xOri = []

    #vrnemo koncno formulo
    return prop.And(l)
コード例 #3
0
ファイル: generate_tests.py プロジェクト: Sandy4321/lvr-sat
def random_phi(length = 10, vars = 10):
	V = ["phi"+str(i) for i in range(vars)]
	phi = []
	i = 0
	while i < length:
		tmp = []
		if i >= length-3: break
		k = rnd.randint(3, length-i-1)
		for j in range(k):
			tmp_var = V[rnd.randint(0, vars-1)]
			# P(negacija formula) = 1/2? 
			if rnd.randint(0, 5) <= 3: tmp.append(prop.Not(tmp_var) if rnd.randint(0,1) == 0 else tmp_var) # E[dolzina] = k * 3/5
			else: break
			i = i+1
		if len(prop.Or(tmp).l) > 0: phi.append(prop.Or(tmp)) # Protislovja spustimo (zato vrnemo formulo dolzine kvecjemu length :-)
		i = i+1
	return prop.And(phi)
コード例 #4
0
def hadamard(n):
    #hadamardove matrike obstajajo le za sode n
    assert n % 2 == 0
    if (n % 2 != 0):
        return prop.Fls()

    l = []

    #predpostavka - prva vrstica so vsi True
    l.append(prop.And(["v0s%d" % i for i in range(n)]))

    #generiramo mozne kombinacije, tako da je n/2 clenov True in n/2 False
    a = list(itertools.combinations(range(n), n / 2))
    #print a;
    #print a;
    #gneriraj vse mozne vrstice | v moz[i] so spravljenje vse mogoce kombinacije spremenljivk za vrstico i
    moz = [[]]
    for i in range(1, n):
        moz.append([])
        for j in range(len(a)):
            moz[i].append(
                prop.And([
                    prop.Not("v" + str(i) + "s%d" % k) if
                    (k not in a[j]) else "v" + str(i) + "s%d" % k
                    for k in range(n)
                ]))
    #print moz;
    #generiraj vse mozne matrike, katerih vrstice bi ustrezale Hadamardovi matriki
    #b = list(itertools.combinations(range(1,n*len(a)), n-1)); #iz vseh moznih vrstic moramo izbrati n-1, ker prvo ze imamo
    #print b;
    moz2 = []

    b = list(itertools.combinations(range(len(moz[1])), n - 1))
    for j in range(1):  #range(len(b)):
        moz2.append(
            prop.And(
                [l[0],
                 prop.And([moz[i][b[j][i - 1]] for i in range(1, n)])]))
    print moz2
    return prop.Or(moz2)
    """
コード例 #5
0
def sudoku2sat(s):
    V = 81
    #stevilo kvadratkov (vozlisc)
    k = 9
    #stevilo barv
    l = []
    #list logicnih formul
    # sudoku je oznacen:
    #
    #	1  2  3  4  5  6  7  8  9
    #	10 11 12 13 14 15 16 17 18
    #	...
    #

    # pretvori sudoku s v 1d seznam
    novS = []
    for i in range(k):
        novS = novS + s[i]
    s = novS
    # print s;

    povVrst = []  # povezani kvadratki v vrsticah
    povStolp = []  # povezani kvadratki v stolpcih
    povKvadr = []  # povezani kvadratki v 3x3 kvadratih

    # Konstriramo graf, 9-barvljiv <==> Sudoku resljiv
    # povezemo kvadratke v vrsticah
    for k in range(0, 9):
        for i in range(1, 10):
            for j in range(i + 1, 10):
                povVrst.append((i + k * 9, j + k * 9))

    #p ovezemo kvadratke v stolpcih
    for i in range(1, 10):  # index stolpca v k-ti vrstici
        for k in range(0, 9):  # index vrstice
            for j in range(k + 1,
                           9):  # stoplci, ki se niso povezavi s k-tim stolpcem
                povStolp.append((i + 9 * k, i + 9 * j))

    #povezemo kvadratke znotraj 3x3 kvadratov
    for i in range(0, 3):
        for j in range(1, 4):
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1) - 10),
                             (j * 3 - 1) + (9 * (3 * i + 1)) + 10))
            # Doda povezavo, ki je manjkala
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1)),
                             (j * 3 - 1) + (9 * (3 * i + 1)) + 10))
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1)),
                             (j * 3 - 1) + (9 * (3 * i + 1)) - 10))
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1) - 8),
                             (j * 3 - 1) + (9 * (3 * i + 1)) + 8))
            # Doda povezav, ki jo manjkala
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1)),
                             (j * 3 - 1) + (9 * (3 * i + 1)) + 8))
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1)),
                             (j * 3 - 1) + (9 * (3 * i + 1)) - 8))
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1) - 1),
                             (j * 3 - 1) + (9 * (3 * i + 1)) - 9))  # /
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1) + 1),
                             (j * 3 - 1) + (9 * (3 * i + 1)) - 9))  # \
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1) - 1),
                             (j * 3 - 1) + (9 * (3 * i + 1)) + 9))  # /
            povKvadr.append(((j * 3 - 1) + (9 * (3 * i + 1) + 1),
                             (j * 3 - 1) + (9 * (3 * i + 1)) + 9))  # \

    povezave = povVrst + povStolp + povKvadr

    # vsako vozlisce ima vsaj eno barvo
    # vozlisca v imajo stevilko v zacetnem sudoku-ju pobarvamo z znano barvo
    #l.append(prop.And([prop.Or(["v%dc%d" % (i, j) for j in range(k)]) for i in range(G[0])]))
    barveVoz = []
    for i in range(1, V + 1):
        if (
                s[i - 1] == None
        ):  #ce je None, je lahko ubistvu kjerekoli barve, ce ne upostevamo pogojev
            barveVoz.append(
                prop.Or(["v%dc%d" % (i, j) for j in range(1, 9 + 1)]))
        else:
            #print str(i)+" "+s[i-1];
            barveVoz.append("v%dc%d" % (i, int(s[i - 1])))
            #ce ni None, ima ze tocno doloceno barvo...
    barveVoz = prop.And(barveVoz)
    l.append(barveVoz)

    barveKraj = []
    # pari krajisc so razlicnih barv
    for (u, v) in povezave:
        if (s[u - 1] != None):
            barveKraj.append(prop.Not("v" + str(v) + "c" + s[u - 1]))
        elif (s[v - 1] != None):
            barveKraj.append(prop.Not("v" + str(u) + "c" + s[v - 1]))
        else:
            for c in range(1, 9 + 1):
                barveKraj.append(
                    prop.Not(
                        prop.And([
                            "v" + str(u) + "c" + str(c),
                            "v" + str(v) + "c" + str(c)
                        ])))
    l.append(prop.And(barveKraj))

    # vsako vozlisce je kvecjemu ene barve
    for v in range(1, V + 1):
        if (s[v - 1] == None):
            for i in range(1, 9 + 1):
                for j in range(i + 1, 9 + 1):
                    l.append(
                        prop.Not(
                            prop.And([
                                "v" + str(v) + "c" + str(i),
                                "v" + str(v) + "c" + str(j)
                            ])))

    return prop.And(l)
コード例 #6
0
def sat3(phi, d=None, variables=None):
    #Izboljsan sta solver z hevristiko, in sicer definirajmo a kot kolikokrat se je pojavila spremenljivka,
    #in b kot dolzino najmanjsega izraza, kjer je spremenljivka nastopala. Hevristika je enaka a/b.
    #Ustvarimo si slovar in mnozico vseh spremenljivk, ce jih ze nimamo
    if not type(d) == dict:
        d = {}
    if not type(variables) == set:
        variables = set()
        prop.allVariables(phi, variables)
    cleanVariables = set()
    unCleanVariables = set()
    heuristicInfo = defaultdict(
        lambda: [0, -1 * sys.maxint + 1
                 ])  #prva komponenta shranjuje, kolikokrat se je spremenljivka
    #pojavila, druga pa, kaksna je velikost najmanjsega izraza, v katerem je sodelovala
    if isinstance(phi, prop.Tru): return prop.Tru(), d
    elif isinstance(phi, prop.Fls): return prop.Fls(), None
    elif isinstance(phi, prop.Or) and len(phi.l) == 0:
        return prop.Fls(
        ), None  #Vcasih se zgodi, da dobimo prazen Or namesto prop.Fls
    elif isinstance(phi, prop.And):
        if len(phi.l) == 0: return prop.Tru(), d  #prazen And pomeni prop.Tru()
        #print len(phi.l)
        for lit in phi.l:
            if isinstance(lit, prop.Fls):
                return prop.Fls(
                ), None  #ce je vsaj eden od elementov Fls, vrnemo fls
            elif isinstance(lit, prop.Or):
                if len(lit.l) == 0:
                    return prop.Fls(
                    ), None  #Prazen stavek, zgolj zaradi varnosti, ampak mislim, da vcasih funkcija apply vrne prazen Or

                for lit2 in lit.l:  #Literali v Or
                    if isinstance(lit2, prop.Not):
                        heuristicInfo[lit2.t.p][1] = min(
                            len(lit.l), heuristicInfo[lit2.t.p][1])
                        heuristicInfo[lit2.t.p][0] += 1
                        if lit2.t in unCleanVariables:
                            pass  #spremenljivka je umazana
                        elif lit2 in cleanVariables:
                            pass  #spremenljivka ostaja cista
                        elif lit2.t in cleanVariables:  # spremenljivka se je umazala
                            unCleanVariables.add(
                                lit2.t)  #spremenljivka gre v umazano sobo
                            cleanVariables.remove(lit2.t)
                        elif lit2 not in cleanVariables and lit2.t not in cleanVariables:  #spremenljivka ima moznost postati cista
                            cleanVariables.add(lit2)
                        else:
                            assert False, "Tu ni vec nic za narediti"
                    elif isinstance(lit2, prop.Literal):
                        heuristicInfo[lit2.p][1] = min(
                            len(lit.l), heuristicInfo[lit2.p][1])
                        heuristicInfo[lit2.p][0] += 1
                        if lit2 in unCleanVariables:
                            pass  #spremenljivka je umazana, zanjo ni resitve
                        elif lit2 in cleanVariables:
                            pass  #spremenljivka je cista, se je upanje
                        elif prop.Not(
                                lit2
                        ) in cleanVariables:  #umazali smo spremenljivko
                            cleanVariables.remove(prop.Not(lit2))
                            unCleanVariables.add(lit2)
                        elif lit2 not in cleanVariables and prop.Not(
                                lit2
                        ) not in cleanVariables:  #spremenljivka ima moznost postati cista
                            cleanVariables.add(lit2)
                        else:
                            assert False, "Tu ni vec nic za narediti"
                    else:
                        assert False, "You shall not pass this door"

            elif isinstance(lit, prop.Not):
                if lit.t.p not in d:  #ce spremenljivke se nismo obravnavali
                    d[lit.t.p] = prop.Fls()
                    variables.remove(lit.t.p)  #smo jo nastavili
                elif lit.t.p in d and d[lit.t.p] == prop.Tru():
                    return prop.Fls(
                    ), None  #ce smo jo obravnavali in jo postavili obratno
                else:
                    pass  #enkrat smo ze nastavljali to spremenljivko
            elif isinstance(lit, prop.Literal):
                #naredimo skoraj enako kot prej
                if lit.p not in d:  #ce spremenljivke se nismo obravnavali
                    d[lit.p] = prop.Tru()
                    #phi = phi.apply(d)
                    variables.remove(lit.p)  #smo jo nastavili
                elif lit.p in d and d[lit.p] == prop.Fls():
                    return prop.Fls(), None
                else:
                    pass  #enkrat smo ze nastavljali to spremenljivko
            else:
                print lit.__class__.__name__
                assert False, "Nemogoce: Je formula res CNF?"

    #pogledamo, ali imamo kaksne ciste spremenljivke, ki jih se nismo spremenili
    for clean in cleanVariables:
        if isinstance(clean, prop.Not):
            if clean.t.p in variables:  #spremenljivke se nismo nastavljali
                d[clean.t.p] = prop.Fls()
                variables.remove(clean.t.p)
            else:
                pass
        elif isinstance(clean, prop.Literal):
            if clean.p in variables:  #spremenljivke se nismo nastavljali
                d[clean.p] = prop.Tru()
                variables.remove(clean.p)

    if len(variables) != 0:  #Nismo se porabili vseh spremenljivk
        candidates = sorted([(1.0 * value[0] / (1.0 * value[1]), key)
                             for key, value in heuristicInfo.iteritems()],
                            reverse=True)

        i = 0
        while (candidates[i][1] not in variables):
            i += 1
        var = candidates[i][1]
        while (var not in variables):
            i += 1
            var = candidates[i][1]
        variables.remove(var)
        d1 = dict(d)
        d1[var] = prop.Tru()
        result, d1 = sat(phi.apply(d1), d1, set(variables))
        if result == prop.Tru(): return result, d1
        d2 = dict(d)
        d2[var] = prop.Fls()
        result, d2 = sat(phi.apply(d2), d2, set(variables))
        if result == prop.Tru(): return result, d2
        return prop.Fls(), None
    else:
        return sat(
            phi.apply(d), d, variables
        )  #koncali delo, stavki na zacetku funkcije poskrbijo za uspesno koncanje metode
コード例 #7
0
def sat(phi, d=None, variables=None):
    #Ustvarimo si slovar in mnozico vseh spremenljivk, ce jih ze nimamo
    if not type(d) == dict:
        d = {}
    if not type(variables) == set:
        variables = set()
        prop.allVariables(phi, variables)
    cleanVariables = set()
    unCleanVariables = set()
    if isinstance(phi, prop.Tru): return prop.Tru(), d
    elif isinstance(phi, prop.Fls): return prop.Fls(), None
    elif isinstance(phi, prop.Or) and len(phi.l) == 0:
        return prop.Fls(
        ), None  #Vcasih se zgodi, da dobimo prazen Or namesto prop.Fls
    elif isinstance(phi, prop.And):
        if len(phi.l) == 0: return prop.Tru(), d  #prazen And pomeni prop.Tru()
        #print len(phi.l)
        for lit in phi.l:
            if isinstance(lit, prop.Fls):
                return prop.Fls(
                ), None  #ce je vsaj eden od elementov Fls, vrnemo fls
            elif isinstance(lit, prop.Or):
                if len(lit.l) == 0:
                    return prop.Fls(
                    ), None  #Prazen stavek, zgolj zaradi varnosti, ampak mislim, da vcasih funkcija apply vrne prazen Or

                for lit2 in lit.l:  #Literali v Or
                    if isinstance(lit2, prop.Not):
                        if lit2.t in unCleanVariables:
                            pass  #spremenljivka je umazana
                        elif lit2 in cleanVariables:
                            pass  #spremenljivka ostaja cista
                        elif lit2.t in cleanVariables:  # spremenljivka se je umazala
                            unCleanVariables.add(
                                lit2.t)  #spremenljivka gre v umazano sobo
                            cleanVariables.remove(lit2.t)
                        elif lit2 not in cleanVariables and lit2.t not in cleanVariables:  #spremenljivka ima moznost postati cista
                            cleanVariables.add(lit2)
                        else:
                            assert False, "Tu ni vec nic za narediti"
                    elif isinstance(lit2, prop.Literal):
                        if lit2 in unCleanVariables:
                            pass  #spremenljivka je umazana, zanjo ni resitve
                        elif lit2 in cleanVariables:
                            pass  #spremenljivka je cista, se je upanje
                        elif prop.Not(
                                lit2
                        ) in cleanVariables:  #umazali smo spremenljivko
                            cleanVariables.remove(prop.Not(lit2))
                            unCleanVariables.add(lit2)
                        elif lit2 not in cleanVariables and prop.Not(
                                lit2
                        ) not in cleanVariables:  #spremenljivka ima moznost postati cista
                            cleanVariables.add(lit2)
                        else:
                            assert False, "Tu ni vec nic za narediti"
                    else:
                        assert False, "You shall not pass this door"

            elif isinstance(lit, prop.Not):
                if lit.t.p not in d:  #ce spremenljivke se nismo obravnavali
                    d[lit.t.p] = prop.Fls()
                    variables.remove(lit.t.p)  #smo jo nastavili
                elif lit.t.p in d and d[lit.t.p] == prop.Tru():
                    return prop.Fls(
                    ), None  #ce smo jo obravnavali in jo postavili obratno
                else:
                    pass  #enkrat smo ze nastavljali to spremenljivko
            elif isinstance(lit, prop.Literal):
                #naredimo skoraj enako kot prej
                if lit.p not in d:  #ce spremenljivke se nismo obravnavali
                    d[lit.p] = prop.Tru()
                    #phi = phi.apply(d)
                    variables.remove(lit.p)  #smo jo nastavili
                elif lit.p in d and d[lit.p] == prop.Fls():
                    return prop.Fls(), None
                else:
                    pass  #enkrat smo ze nastavljali to spremenljivko
            else:
                print lit.__class__.__name__
                assert False, "NNemogoce: Je formula res CNF?"

    #pogledamo, ali imamo kaksne ciste spremenljivke, ki jih se nismo spremenili
    for clean in cleanVariables:
        if isinstance(clean, prop.Not):
            if clean.t.p in variables:  #spremenljivke se nismo nastavljali
                d[clean.t.p] = prop.Fls()
                variables.remove(clean.t.p)
            else:
                pass
        elif isinstance(clean, prop.Literal):
            if clean.p in variables:  #spremenljivke se nismo nastavljali
                d[clean.p] = prop.Tru()
                variables.remove(clean.p)

    if len(variables) != 0:  #Nismo se porabili vseh spremenljivk
        var = random.sample(variables, 1)[0]  #si izberemo eno
        variables.remove(var)
        d1 = dict(d)
        d1[var] = prop.Tru()
        result, d1 = sat(phi.apply(d1), d1, set(variables))
        if result == prop.Tru(): return result, d1
        d2 = dict(d)
        d2[var] = prop.Fls()
        result, d2 = sat(phi.apply(d2), d2, set(variables))
        if result == prop.Tru(): return result, d2
        return prop.Fls(), None
    else:
        return sat(
            phi.apply(d), d, variables
        )  #koncali delo, stavki na zacetku funkcije poskrbijo za uspesno koncanje metode
コード例 #8
0
def sat2(phi, d=None, variables=None):
    #Izboljsan sta solver z hevristiko. Izberemo spremenljivko, ki se je pojavila v najmanjsem izrazu;
    # v primeru izenacenja izberemo tisto, ki se je pojavila najveckrat
    #Ustvarimo si slovar in mnozico vseh spremenljivk, ce jih ze nimamo
    if not type(d) == dict:
        d = {}
    if not type(variables) == set:
        variables = set()
        prop.allVariables(phi, variables)
    cleanVariables = set()
    unCleanVariables = set()
    expressionSize = PriorityQueue(
    )  #struktura bo shranjevala, v kako velikem izrazu se spremenljivka pojavi.
    nrOfApperances = defaultdict(lambda: 0)
    if isinstance(phi, prop.Tru): return prop.Tru(), d
    elif isinstance(phi, prop.Fls): return prop.Fls(), None
    elif isinstance(phi, prop.Or) and len(phi.l) == 0:
        return prop.Fls(
        ), None  #Vcasih se zgodi, da dobimo prazen Or namesto prop.Fls
    elif isinstance(phi, prop.And):
        if len(phi.l) == 0: return prop.Tru(), d  #prazen And pomeni prop.Tru()
        #print len(phi.l)
        for lit in phi.l:
            if isinstance(lit, prop.Fls):
                return prop.Fls(
                ), None  #ce je vsaj eden od elementov Fls, vrnemo fls
            elif isinstance(lit, prop.Or):
                if len(lit.l) == 0:
                    return prop.Fls(
                    ), None  #Prazen stavek, zgolj zaradi varnosti, ampak mislim, da vcasih funkcija apply vrne prazen Or

                for lit2 in lit.l:  #Literali v Or
                    if isinstance(lit2, prop.Not):
                        expressionSize.put((len(lit.l), lit2.t.p))
                        nrOfApperances[lit2.t.p] += 1
                        if lit2.t in unCleanVariables:
                            pass  #spremenljivka je umazana
                        elif lit2 in cleanVariables:
                            pass  #spremenljivka ostaja cista
                        elif lit2.t in cleanVariables:  # spremenljivka se je umazala
                            unCleanVariables.add(
                                lit2.t)  #spremenljivka gre v umazano sobo
                            cleanVariables.remove(lit2.t)
                        elif lit2 not in cleanVariables and lit2.t not in cleanVariables:  #spremenljivka ima moznost postati cista
                            cleanVariables.add(lit2)
                        else:
                            assert False, "Tu ni vec nic za narediti"
                    elif isinstance(lit2, prop.Literal):
                        expressionSize.put((len(lit.l), lit2.p))
                        nrOfApperances[lit2.p] += 1
                        if lit2 in unCleanVariables:
                            pass  #spremenljivka je umazana, zanjo ni resitve
                        elif lit2 in cleanVariables:
                            pass  #spremenljivka je cista, se je upanje
                        elif prop.Not(
                                lit2
                        ) in cleanVariables:  #umazali smo spremenljivko
                            cleanVariables.remove(prop.Not(lit2))
                            unCleanVariables.add(lit2)
                        elif lit2 not in cleanVariables and prop.Not(
                                lit2
                        ) not in cleanVariables:  #spremenljivka ima moznost postati cista
                            cleanVariables.add(lit2)
                        else:
                            assert False, "Tu ni vec nic za narediti"
                    else:
                        assert False, "You shall not pass this door"

            elif isinstance(lit, prop.Not):
                if lit.t.p not in d:  #ce spremenljivke se nismo obravnavali
                    d[lit.t.p] = prop.Fls()
                    variables.remove(lit.t.p)  #smo jo nastavili
                elif lit.t.p in d and d[lit.t.p] == prop.Tru():
                    return prop.Fls(
                    ), None  #ce smo jo obravnavali in jo postavili obratno
                else:
                    pass  #enkrat smo ze nastavljali to spremenljivko
            elif isinstance(lit, prop.Literal):
                #naredimo skoraj enako kot prej
                if lit.p not in d:  #ce spremenljivke se nismo obravnavali
                    d[lit.p] = prop.Tru()
                    #phi = phi.apply(d)
                    variables.remove(lit.p)  #smo jo nastavili
                elif lit.p in d and d[lit.p] == prop.Fls():
                    return prop.Fls(), None
                else:
                    pass  #enkrat smo ze nastavljali to spremenljivko
            else:
                print lit.__class__.__name__
                assert False, "Nemogoce: Je formula res CNF?"

    #pogledamo, ali imamo kaksne ciste spremenljivke, ki jih se nismo spremenili
    for clean in cleanVariables:
        if isinstance(clean, prop.Not):
            if clean.t.p in variables:  #spremenljivke se nismo nastavljali
                d[clean.t.p] = prop.Fls()
                variables.remove(clean.t.p)
            else:
                pass
        elif isinstance(clean, prop.Literal):
            if clean.p in variables:  #spremenljivke se nismo nastavljali
                d[clean.p] = prop.Tru()
                variables.remove(clean.p)

    if len(variables) != 0:  #Nismo se porabili vseh spremenljivk
        candidates = []
        if (expressionSize.empty() == True):
            assert False, "Morajo biti vsaj nekatere spremenljivke"
        cand = expressionSize.get()
        while (cand[1] not in variables
               ):  #Izberemo prvo spremenljivko, ki se ni bila dolocena
            if (expressionSize.empty() == True):
                assert False, "Morajo biti vsaj nekatere spremenljivke"
            cand = expressionSize.get()
        candidates.append(cand)
        while (not (expressionSize.empty()
                    == True)):  #dodamo vse, ki so izenacene
            cand = expressionSize.get()
            if candidates[0][0] != cand[0]: break
            candidates.append(cand)
        candidates = sorted([(nrOfApperances[cand[1]], cand[1])
                             for cand in candidates],
                            reverse=True)
        i = 0
        var = candidates[i][1]
        while (var not in variables):
            i += 1
            var = candidates[i][1]
        variables.remove(var)
        d1 = dict(d)
        d1[var] = prop.Tru()
        result, d1 = sat(phi.apply(d1), d1, set(variables))
        if result == prop.Tru(): return result, d1
        d2 = dict(d)
        d2[var] = prop.Fls()
        result, d2 = sat(phi.apply(d2), d2, set(variables))
        if result == prop.Tru(): return result, d2
        return prop.Fls(), None
    else:
        return sat(
            phi.apply(d), d, variables
        )  #koncali delo, stavki na zacetku funkcije poskrbijo za uspesno koncanje metode
コード例 #9
0
    j = n = len(L)
    while True:
        R.append(L[1:])
        j = n - 1
        # NOTE: Changing `L[j] == 1' to `L[j] == mi' will generate [m1] x [m2] x ... x [mn], where [mi] denotes {1,2, ..., mi}
        while j > 0 and L[j] == 1:
            L[j] = 0
            j = j - 1
        L[j] = L[j] + 1
        if j == 0: break
    return R


# tries all possible assignments
def brute_force(phi):
    # TODO: Get a list of variables from phi; then feed the list to comb() to get all possible assignments
    for asg in comb([0, 0, 0, 0, 0, 0, 0, 0]):
        print asg
        # print { i : asg[i] for i in range(len(asg)) }


# Vstopna tocka
if __name__ == "__main__":
    phi = prop.And([("a"), "a",
                    prop.Or(prop.Not("b"), "d"), "c",
                    prop.Or([prop.Not("b"), "a"])]).cnf()
    print phi
    print satBruteForce(phi)
    print sat(phi)
    print sat3(phi)
コード例 #10
0
ファイル: edp.py プロジェクト: Sandy4321/lvr-sat
#
# Klicemo rahlo spremenjen zunanji C++ program, ki sta ga objavila B. Konev in A. Lisista. Program
# vrne SAT instanco v CNF, ki ustreza Erdosevemu problemu diskrepance za dane parametre. Formulo
# pretvorimo v primerno obliko in jo nahranimo nasemu solverju.
#

import prop
import math
import re
import itertools
import sat
import os

clean = lambda v: prop.Not("v" + v[1:]) if v[0] == '-' else "v" + v


def edp2sat(fname):
    L = open(fname).read().split('\n')
    fmt = L[0]
    return prop.And([
        prop.Or([clean(c) for c in clause.split()[:-1]]) for clause in L[1:-1]
    ])


if __name__ == '__main__':
    length = 4
    discrepancy = 1
    bits = 5
    cmd = 'sat14 %d %d %d > out.cnf' % (length, discrepancy, bits)
    print "Compiling sat14.cc..."
    os.system('g++ sat14.cc -o sat14')
コード例 #11
0
ファイル: generate_tests.py プロジェクト: Sandy4321/lvr-sat
			i = i+1
		if len(prop.Or(tmp).l) > 0: phi.append(prop.Or(tmp)) # Protislovja spustimo (zato vrnemo formulo dolzine kvecjemu length :-)
		i = i+1
	return prop.And(phi)

# Vzame seznam literalov; ga nakljucno permutira; razbije na k delov; vrne konjunkcijo. (Hvala prof. Bauerju za kul predlog. :-)
def rnd_cnf(literals, k = 3):
	literals = shuffle(literals)
	n = len(literals)
	return prop.And([prop.Or(literals[i*n/k:(i+1)*n/k]) for i in range(n/k)])

# Vrne ``tezko'' instanco SAT problema 
# Ideja: Generiraj DNF na enak nacin pri rnd_cnf; vrni CNF.
def hard_phi(literals, k = 3):
	literals = shuffle(literals)
	n = len(literals)
	L = [prop.And(literals[i*n/k:(i+1)*n/k]) for i in range(n/k)]
	L.append(literals[0])
	print L
	return prop.Or(L).cnf()

# Vstopna tocka; nekaj testov; samo za okus 
if __name__ == "__main__":
    j=6
    literals = [prop.Not("v"+str(i)) for i in range(j)]
    literals = literals + ["v"+str(i) for i in range(j)]
    phi = hard_phi(literals, 3)
    print phi
    print sat.sat(phi)
    print sat.sat2(phi)
コード例 #12
0
def sudoku(s):
	V = 81; #stevilo kvadratkov (vozlisc)
	k = 9; #stevilo barv
	l = []; #list logicnih formul
	#sudoku je oznacen:
	"""
		1  2  3  4  5  6  7  8  9
		10 11 12 13 14 15 16 17 18
		...
	"""
	
	#pretvori sudoku s v 1d seznam
	novS = [];
	for i in range(k):
		novS = novS + s[i];
	s = novS;
	#print s;

	povVrst = [] #povezani kvadratki v vrsticah
	povStolp = [] #povezani kvadratki v stolpcih
	povKvadr = [] #povezani kvadratki v 3x3 kvadratih
	"""
	for i in range(1, 82):
		if (i % 9 != 0 and i != 81):
			povVrst.append((i,i+1)); #delamo povezave vrstic
		if (i < 73):
			povStolp.append((i,9+i)); #delamo povezave stolpcev
	"""
	# Konstriramo graf, 9-barvljiv <==> Sudoku resljiv 
	#povezemo kvadratke v vrsticah
	for k in range(0,9):
		for i in range(1,10):
			for j in range(i+1, 10):
				povVrst.append((i+k*9, j+k*9));
	
	#povezemo kvadratke v stolpcih
	for i in range(1,10): # index stolpca v k-ti vrstici 
		for k in range(0,9): # index vrstice 
			for j in range(k+1, 9): # stoplci, ki se niso povezavi s k-tim stolpcem 
				povStolp.append((i+9*k, i+9*j));
	
	
			
	#print povVrst;
	#print povStolp;
			
	#povezemo kvadratke znotraj 3x3 kvadratov
	for i in range(0,3):
		for j in range(1,4):
			#povKvadr.append(((j*3-1)+(9*(3*i+1)), (j*3-1)+(9*(3*i+1))+1));
			#povKvadr.append(((j*3-1)+(9*(3*i+1)), (j*3-1)+(9*(3*i+1))-1));
			#povKvadr.append(((j*3-1)+(9*(3*i+1)), (j*3-1)+(9*(3*i+1))+9));
			#povKvadr.append(((j*3-1)+(9*(3*i+1)), (j*3-1)+(9*(3*i+1))-9));
			povKvadr.append(((j*3-1)+(9*(3*i+1)-10), (j*3-1)+(9*(3*i+1))+10)); # Doda povezavo, ki je manjkala 
			povKvadr.append(((j*3-1)+(9*(3*i+1)), (j*3-1)+(9*(3*i+1))+10));
			povKvadr.append(((j*3-1)+(9*(3*i+1)), (j*3-1)+(9*(3*i+1))-10));
			povKvadr.append(((j*3-1)+(9*(3*i+1)-8), (j*3-1)+(9*(3*i+1))+8)); # Doda povezav, ki jo manjkala 
			povKvadr.append(((j*3-1)+(9*(3*i+1)), (j*3-1)+(9*(3*i+1))+8));
			povKvadr.append(((j*3-1)+(9*(3*i+1)), (j*3-1)+(9*(3*i+1))-8));
			povKvadr.append(((j*3-1)+(9*(3*i+1)-1), (j*3-1)+(9*(3*i+1))-9)) # /
			povKvadr.append(((j*3-1)+(9*(3*i+1)+1), (j*3-1)+(9*(3*i+1))-9)) # \
			povKvadr.append(((j*3-1)+(9*(3*i+1)-1), (j*3-1)+(9*(3*i+1))+9)) # /
			povKvadr.append(((j*3-1)+(9*(3*i+1)+1), (j*3-1)+(9*(3*i+1))+9)) # \
	#print povKvadr;
	
	povezave = povVrst + povStolp + povKvadr;
	#povezave = povVrst + povKvadr;
	#povezave = list(set(povezave)); #odstranimo duplikate povezav 
	#print povezave
	
	# vsako vozlisce ima vsaj eno barvo
	# vozlisca v imajo stevilko v zacetnem sudoku-ju pobarvamo z znano barvo
	#l.append(prop.And([prop.Or(["v%dc%d" % (i, j) for j in range(k)]) for i in range(G[0])]))
	barveVoz = [];
	for i in range(1, V+1):
		if(s[i-1] == None): #ce je None, je lahko ubistvu kjerekoli barve, ce ne upostevamo pogojev
			barveVoz.append(prop.Or(["v%dc%d" % (i, j) for j in range(1, 9+1)]));
		else:
			#print str(i)+" "+s[i-1];
			barveVoz.append("v%dc%d" % (i, int(s[i-1]))); #ce ni None, ima ze tocno doloceno barvo...
	barveVoz = prop.And(barveVoz);
	l.append(barveVoz);
	#print barveVoz;
	
	barveKraj = [];
	# pari krajisc so razlicnih barv 
	for (u, v) in povezave:
		if(s[u-1] != None):
			#barveKraj.append(prop.Not(prop.And(["v"+str(u)+"c"+s[u-1], "v"+str(v)+"c"+s[u-1]])));
			barveKraj.append(prop.Not("v"+str(v)+"c"+s[u-1]));
		elif(s[v-1] != None):
			#barveKraj.append(prop.Not(prop.And(["v"+str(u)+"c"+s[v-1], "v"+str(v)+"c"+s[v-1]])));
			barveKraj.append(prop.Not("v"+str(u)+"c"+s[v-1]));
		else:
			for c in range(1, 9+1):
				barveKraj.append(prop.Not(prop.And(["v"+str(u)+"c"+str(c), "v"+str(v)+"c"+str(c)])));
		#l.append(prop.And([prop.And([prop.Not(prop.And(["v"+str(u)+"c"+str(c), "v"+str(v)+"c"+str(c)])) for c in range(k)])]))
	#print barveKraj;
	l.append(prop.And(barveKraj));
	#print l;
	# print "BARVEEEEE", k
	# vsako vozlisce je kvecjemu ene barve 
	for v in range(1, V+1):
		if(s[v-1] == None):
			for i in range(1, 9+1):
				for j in range(i+1, 9+1):
					l.append(prop.Not(prop.And(["v"+str(v)+"c"+str(i), "v"+str(v)+"c"+str(j)])))
		
	l = prop.And(l);

	#print l;
	
	return l;