Esempio n. 1
0
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()
Esempio n. 2
0
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)
Esempio n. 3
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)
Esempio n. 4
0
def test1():
    ## Sestavljanje in manipuliranje formul ##
    # Sestavimo zelo enostavno formulo u \/ v
    phi = prop.Or(["v", "u"])

    ## Uporaba SAT solverjev ##
    # Test DPLL SAT solverja
    print "*" * 80
    print "Testiram DPLL SAT solver"
    dpll_sat_test(phi)
    # Test bruteforce SAT solverja
    print "*" * 80
    print "Testiram bruteforce SAT solver"
    bf_sat_test(phi)

    ## Prevedbe ##
    print "*" * 80
    print "*" * 80
    print "Testiram prevedbe"
    # k-barvanje grafov
    print "*" * 80
    print "Barvanje grafov"
    k = 2  # dvodelnost
    G = (3, [(0, 1), (1, 2), (0, 2)])
    phi = p.graph_coloring2sat(G, k)
    print phi
    # return
    # Sudoku
    print "*" * 80
    print "Sudoku"
    S = h.get_sudoku('sudoku01a.in')
    phi = p.sudoku2sat(S)
    print phi
    x = sat.sat(phi.cnf())
    print S
    print p.solveSudoku(S, x)
    # return
    # Hadamard
    print "*" * 80
    print "Hadamard"
    phi = hadamard(4)
    print phi
    # return
    # Erdosev problem diskrepance
    print "*" * 80
    print "Erdosev problem diskrepance"
    phi = edp(1, 5)
    print phi
Esempio n. 5
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)
    """
Esempio n. 6
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
Esempio n. 7
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)
Esempio n. 8
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)
Esempio n. 9
0
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]
    ])
Esempio n. 10
0
def parse_output(fname = 'new.cnf'):
	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]])
Esempio n. 11
0
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)])
Esempio n. 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;