示例#1
0
def hadamard(n):
    """Vrne logični izraz, ki je izpolnljiv, ko obstaja Hadamardova matrika
    reda n."""
    if n == 1:
        return prop.Literal("r0c0")
    if n % 2 == 1:
        return prop.Fls()
        
    # Prva vrstica in stolpec
    l = ["r0c0"]
    for i in range(1, n):
        l.append("r0c%d" % i)
        l.append("r%dc0" % i)
        
    # Štejemo resnične vrednosti XORa i-te in j-te vrstice
    for i in range(n):
        for j in range(i+1, n):
            # Resničnih je n/2
            l.append("r%dr%df%dn%d" % (i, j, n, n//2))
            # Pravili za prvega
            l.append("r%dr%df1n0" % (i, j))
            l.append(prop.Not("r%dr%df1n1" % (i, j)))
            for k in range(1, n):
                # Ali do indeksa k ni nobenega resničnega?
                l.append(prop.iff("r%dr%df%dn0" % (i, j, k+1), prop.And("r%dr%df%dn0" % (i, j, k), prop.iff("r%dc%d" % (i, k), "r%dc%d" % (j, k)))))
                if k < n//2:
                    # Ali so do indeksa k vsi resnični?
                    l.append(prop.iff("r%dr%df%dn%d" % (i, j, k+1, k+1), prop.And("r%dr%df%dn%d" % (i, j, k, k), prop.Not(prop.iff("r%dc%d" % (i, k), "r%dc%d" % (j, k))))))
                for m in range(min(k, n//2)):
                    # Ali je do indeksa k m+1 resničnih?
                    l.append(prop.iff("r%dr%df%dn%d" % (i, j, k+1, m+1), prop.Or(prop.And("r%dr%df%dn%d" % (i, j, k, m), prop.Not(prop.iff("r%dc%d" % (i, k), "r%dc%d" % (j, k)))), prop.And("r%dr%df%dn%d" % (i, j, k, m+1), prop.iff("r%dc%d" % (i, k), "r%dc%d" % (j, k))))))
    return prop.And(l)
示例#2
0
def sudoku(s, abc):
    """Vrne logični izraz, ki opisuje sudoku s z abecedo abc."""
    n = len(abc)
    r = int(math.sqrt(n))
    
    if isinstance(abc, basestring):
        s = [[None if s[i][j] in [None, ""] else str(s[i][j]) for j in range(n)] for i in range(n)]
        assert all([all([x == None or (len(x) == 1 and x in abc) for x in l]) for l in s]), "Sudoku vsebuje neveljavne simbole!"
    else:
        assert None not in abc, "Abeceda ne sme vsebovati None!"
        assert all([all([x == None or x in abc for x in l]) for l in s]), "Sudoku vsebuje neveljavne simbole!"
    
    assert n == r*r, "Velikost abecede ni popoln kvadrat!"
    assert len(s) == n, "Število vrstic se ne ujema s številom znakov!"
    assert all([len(l) == n for l in s]), "Število stolpcev se ne ujema s številom znakov!"
    
    l = []
    
    for i in range(n):
        for j in range(n):
            if s[i][j] != None:
                # Obstoječa števila
                t = abc.index(s[i][j])
                for k in range(n):
                    if k == t:
                        l.append("r%dc%dv%d" % (i, j, k))
                    else:
                        l.append(prop.Not("r%dc%dv%d" % (i, j, k)))
            else:
                # Vsako polje ima natanko eno vrednost
                for k in range(n):
                    l.append(prop.iff("r%dc%do%d" % (i, j, k), prop.And([("r%dc%dv%d" % (i, j, x) if x == k else prop.Not("r%dc%dv%d" % (i, j, x))) for x in range(n)])))
                l.append(prop.Or(["r%dc%do%d" % (i, j, k) for k in range(n)]))
            # V vsaki vrstici se pojavi vsaka vrednost
            l.append(prop.Or(["r%dc%dv%d" % (j, x, i) for x in range(n)]))
            # V vsakem stolpcu se pojavi vsaka vrednost
            l.append(prop.Or(["r%dc%dv%d" % (x, j, i) for x in range(n)]))
    
        # V vsakem kvadratu se pojavi vsaka vrednost
        for j in range(r):
            for k in range(r):
                l.append(prop.Or(sum([["r%dc%dv%d" % (r*j+x, r*k+y, i) for x in range(r)] for y in range(r)], [])))
            
    return prop.And(l)