Sophie

Sophie

distrib > Mandriva > 2010.2 > i586 > media > contrib-backports > by-pkgid > df29c83ca401d91ec9c00bfcf7fea4ea > files > 206

shedskin-0.8-2mdv2010.2.i586.rpm

# pisang - a simple sat solver in Python
# (c) mark.dufour@gmail.com

argv = ['','testdata/uuf250-010.cnf']

cnf = [l.strip().split() for l in file(argv[1]) if l[0] not in 'c%0\n']
clauses = [[int(x) for x in m[:-1]] for m in cnf if m[0] != 'p']
nrofvars = [int(n[2]) for n in cnf if n[0] == 'p'][0]
vars = range(nrofvars+1)
occurrence = [[] for l in vars+range(-nrofvars,0)]
for clause in clauses:
    for lit in clause: occurrence[lit].append(clause)
fixedt = [-1 for var in vars]

def solve_rec():
    global nodecount
    nodecount += 1

    if not -1 in fixedt[1:]:
        print 'v', ' '.join([str((2*fixedt[i]-1)*i) for i in vars[1:]])
        return 1

    la_mods = []
    var = lookahead(la_mods)
    if not var:
        return backtrack(la_mods)
    for choice in [var, -var]:
        prop_mods = []
        if propagate(choice, prop_mods) and solve_rec():
            return 1
        backtrack(prop_mods)
    return backtrack(la_mods)

def propagate(lit, mods):
    global bincount

    current = len(mods)
    mods.append(lit)

    while 1:
        if fixedt[abs(lit)] == -1:
            fixedt[abs(lit)] = int(lit>0)
            for clause in occurrence[-lit]:
                cl_len = length(clause)
                if cl_len == 0:
                    return 0
                elif cl_len == 1:
                    mods.append(unfixed(clause))
                elif cl_len == 2:
                    bincount += 1

        elif fixedt[abs(lit)] != (lit>0):
            return 0

        current += 1
        if current == len(mods):
            break
        lit = mods[current]

    return 1

def lookahead(mods):
    global bincount

    dif = [-1 for var in vars]
    for var in unfixed_vars():
        score = []
        for choice in [var, -var]:
            prop_mods = []
            bincount = 0
            prop = propagate(choice, prop_mods)
            backtrack(prop_mods)
            if not prop:
                if not propagate(-choice, mods):
                    return 0
                break
            score.append(bincount)
        dif[var] = reduce(lambda x, y: 1024*x*y+x+y, score, 0)

    return dif.index(max(dif))

def backtrack(mods):
    for lit in mods:
        fixedt[abs(lit)] = -1
    return 0

def length(clause):
    len = 0
    for lit in clause:
        fixed = fixedt[abs(lit)]
        if fixed == (lit>0):
            return -1
        if fixed == -1:
            len += 1
    return len

def unfixed(clause):
    for lit in clause:
        fixed = fixedt[abs(lit)]
        if fixed == -1:
            return lit

def unfixed_vars():
    return [var for var in vars[1:] if fixedt[var] == -1]

nodecount = 0
if not solve_rec():
    print 'unsatisfiable', nodecount