Example #1
0
    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card', 1) + 1, 2)))
        n = k * int(math.ceil(float(len(self.ab_vars)) / k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(
                lambda x: x + 1, self.ab_vars
            )  # +1 because the CNF vars start from 1 while we start from 0
            vars_padded = dict(self.vars)
            for i in xrange(
                    max(self.vars) + 2,
                    max(self.vars) + (n - len(self.ab_vars)) +
                    2):  # +1: same reaseon as above
                ab_vars_padded += [i]
                vars_padded[i] = 'temp'
                self.cnf_cn += "\n-%d 0" % i
                self.stats['net_clauses'] = self.stats.get('net_clauses',
                                                           0) + 1

            self.cn = CardinalityNetwork(list(ab_vars_padded),
                                         next_var=max(vars_padded) + 2)
            net_clauses = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in net_clauses:
                self.cnf_cn += "\n" + " ".join(map(str, c + [0]))
            self.stats['net_clauses'] = self.stats.get('net_clauses',
                                                       0) + len(net_clauses)
Example #2
0
    def construct_cardinality_network(self, **options):

        self.mapping = dict(enumerate(self.options.get('ab_vars', []), 1))
        self.ab_vars = self.mapping.keys()
        k = 2**int(math.ceil(math.log(options.get('max_card', 1) + 1, 2)))
        n = k * int(math.ceil(float(len(self.ab_vars)) / k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"

            #            print "constructing network for k=%d" % k

            ab_vars_padded = map(lambda x: x, self.ab_vars)

            for i in xrange(
                    max(self.ab_vars) + 1,
                    max(self.ab_vars) + (n - len(self.ab_vars)) + 1):
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                self.description.variables.append(
                    Variable("cn_%d" % i, Variable.BOOLEAN, False))
                self.mapping[i] = "cn_%d" % i


#            print self.ab_vars
#            print ab_vars_padded

            self.cn = CardinalityNetwork(list(ab_vars_padded),
                                         next_var=max(ab_vars_padded) + 1)
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)

            #            print self.clauses_cn
            #            print self.cn.vars

            for i in range(max(ab_vars_padded) + 1, max(self.cn.vars) + 1):
                self.description.variables.append(
                    Variable("cn_%d" % i, Variable.BOOLEAN, None))
                self.mapping[i] = "cn_%d" % i

            self.code_cn = ""
            for clause in self.clauses_cn:
                self.code_cn += "\n(assert (or " + " ".join(
                    [("(not " if l < 0 else "") + self.mapping[abs(l)] +
                     (")" if l < 0 else "") for l in clause]) + "))"
Example #3
0
    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card', 1) + 1, 2)))
        n = k * int(math.ceil(float(len(self.ab_vars)) / k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x, self.ab_vars)
            for i in xrange(options['num_vars'] + 1,
                            options['num_vars'] + (n - len(self.ab_vars)) +
                            1):  # +1: same reaseon as above
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                options['num_vars'] += 1

            self.cn = CardinalityNetwork(list(ab_vars_padded),
                                         next_var=options['num_vars'] + 1)
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in self.clauses_cn:
                self.cnf_cn += "\n" + " ".join(map(str, c + [0]))
Example #4
0
    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card',1)+1,2)))
        n = k*int(math.ceil(float(len(self.ab_vars))/k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x, self.ab_vars)
            for i in xrange(options['num_vars']+1, options['num_vars']+(n-len(self.ab_vars))+1):    # +1: same reaseon as above
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                options['num_vars'] += 1
           
            self.cn = CardinalityNetwork(list(ab_vars_padded), next_var=options['num_vars']+1)
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in self.clauses_cn:
                self.cnf_cn += "\n" + " ".join(map(str, c+[0]))
Example #5
0
    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card',1)+1,2)))
        n = k*int(math.ceil(float(len(self.ab_vars))/k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x+1, self.ab_vars)    # +1 because the CNF vars start from 1 while we start from 0
            vars_padded = dict(self.vars) 
            for i in xrange(max(self.vars)+2, max(self.vars)+(n-len(self.ab_vars))+2):    # +1: same reaseon as above
                ab_vars_padded += [i]
                vars_padded[i] = 'temp'
                self.cnf_cn += "\n-%d 0" % i
                self.stats['net_clauses'] = self.stats.get('net_clauses',0) + 1
            
            self.cn = CardinalityNetwork(list(ab_vars_padded), next_var=max(vars_padded)+2)
            net_clauses = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in net_clauses:
                self.cnf_cn += "\n" + " ".join(map(str, c+[0]))
            self.stats['net_clauses'] = self.stats.get('net_clauses',0) + len(net_clauses)
Example #6
0
    def construct_cardinality_network(self, **options):

        self.mapping = dict(enumerate(self.options.get('ab_vars', []), 1))
        self.ab_vars = self.mapping.keys()
        k = 2**int(math.ceil(math.log(options.get('max_card',1)+1,2)))
        n = k*int(math.ceil(float(len(self.ab_vars))/k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            
#            print "constructing network for k=%d" % k
            
            ab_vars_padded = map(lambda x: x, self.ab_vars)
            
            for i in xrange(max(self.ab_vars)+1, max(self.ab_vars)+(n-len(self.ab_vars))+1):
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                self.description.variables.append(Variable("cn_%d"%i, Variable.BOOLEAN, False))
                self.mapping[i] = "cn_%d"%i
                
#            print self.ab_vars
#            print ab_vars_padded
           
            self.cn = CardinalityNetwork(list(ab_vars_padded), next_var=max(ab_vars_padded)+1)
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)
            
#            print self.clauses_cn
#            print self.cn.vars
            
            for i in range(max(ab_vars_padded)+1, max(self.cn.vars)+1):
                self.description.variables.append(Variable("cn_%d"%i, Variable.BOOLEAN, None))
                self.mapping[i] = "cn_%d"%i

            self.code_cn = ""
            for clause in self.clauses_cn:
                self.code_cn += "\n(assert (or " + " ".join([("(not " if l < 0 else "") + self.mapping[abs(l)] + (")" if l < 0 else "") for l in clause]) + "))"
Example #7
0
class YicesCnEngine(Engine):
    
    def __init__(self, options):
        super(YicesCnEngine, self).__init__(options)
        
        self.sentence_interpreters.update(SENTENCE_INTERPRETERS_CN)
        
        self.cnf = ""
        self.cnf_cn = ""
        self.vars = {}
        self.cn_k = 0
        self.stats = {}
        
    def to_dimacs_literal(self, literal, variable_map):
        if literal.sign == True:
            return str(variable_map.get_key(literal.name)+1)
        else:
            return "-" + str(variable_map.get_key(literal.name)+1)
    
    def to_dimacs_clause(self, clause, variable_map):
        literals = map(lambda l: self.to_dimacs_literal(l, variable_map), clause.literals)
        return " ".join(literals) + " 0"

    def start_again(self, new_sentences, **options):
        super(YicesCnEngine, self).start_again(new_sentences, **options)
        clauses = self.interpret_sentences(new_sentences)
        for c in clauses:
            self.cnf += "\n" + self.to_dimacs_clause(c, self.vars)
        self.stats['cnf_clauses'] += len(clauses)
            
        self.construct_cardinality_network(**options)
        
        self.stats['num_rules'] = self.stats.get('cnf_clauses',0) + self.stats.get('net_clauses',0) + 1
        self.stats['num_vars']  = max(self.cn.vars)

#        cnf  = "p cnf %d %d\n" % (self.stats['num_vars'], self.stats['num_rules']) + self.cnf + self.cnf_cn
        cnf = self.cnf + self.cnf_cn
        cnf += "\n\n-%d 0\n" % self.cn.vars[options.get('max_card',1)] 

        p = SimpleYicesWrapper()
        p.start(SimpleDescription(cnf, self.stats['num_vars'], self.stats['num_rules']))
        self.result = self.parse_output(p.outlines, self.vars, self.ab_vars)
        return self.result
    
    def start(self, description=None, **options):
        super(YicesCnEngine, self).start(description, **options)
        
        if not self.cnf:
            vars = sorted(self.description.get_variables(), key=lambda x: not x.name.startswith("AB"))
            self.vars = TwoWayDict(dict((i, v.name) for i,v in enumerate(vars)))
            self.ab_vars = [i for i,n in self.vars.iteritems() if n.startswith("AB")]
            sentences = self.description.get_sentences()
            for v in self.description.get_variables():
                if v.value is not None:
                    sentences.append(Clause([Literal(v.name, v.value)])) 
            self.core_map = {}
            self.clauses = self.interpret_sentences(sentences)
            
            for c in self.clauses:
                self.cnf += "\n" + self.to_dimacs_clause(c, self.vars)
            
            self.stats['cnf_clauses'] = len(self.clauses)

        self.construct_cardinality_network(**options)

        self.stats['num_rules'] = self.stats.get('cnf_clauses',0) + self.stats.get('net_clauses',0) + 1
        self.stats['num_vars']  = max(self.cn.vars)

#        cnf  = "p cnf %d %d\n" % (self.stats['num_vars'], self.stats['num_rules']) + self.cnf + self.cnf_cn
        cnf = self.cnf + self.cnf_cn
        cnf += "\n\n-%d 0\n" % self.cn.vars[options.get('max_card',1)] 
        
        p = SimpleYicesWrapper()
        p.start(SimpleDescription(cnf, self.stats['num_vars'], self.stats['num_rules']))
        
        self.result = self.parse_output(p.outlines, self.vars, self.ab_vars)
        return self.result

    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card',1)+1,2)))
        n = k*int(math.ceil(float(len(self.ab_vars))/k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x+1, self.ab_vars)    # +1 because the CNF vars start from 1 while we start from 0
            vars_padded = dict(self.vars) 
            for i in xrange(max(self.vars)+2, max(self.vars)+(n-len(self.ab_vars))+2):    # +1: same reaseon as above
                ab_vars_padded += [i]
                vars_padded[i] = 'temp'
                self.cnf_cn += "\n-%d 0" % i
                self.stats['net_clauses'] = self.stats.get('net_clauses',0) + 1
           
            self.cn = CardinalityNetwork(list(ab_vars_padded), next_var=max(vars_padded)+2)
#            print "constructing CN in yices"
            net_clauses = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in net_clauses:
                self.cnf_cn += "\n" + " ".join(map(str, c+[0]))
            self.stats['net_clauses'] = self.stats.get('net_clauses',0) + len(net_clauses)
        

    def interpret_sentences(self, sentences):
        interpreted_sentences = []
        for s in sentences:
            if type(s) in self.sentence_interpreters:
                interpreted_sentences.extend(self.interpret_sentence(s))
            else:
                interpreted_sentences.append(s)
        return interpreted_sentences

    def interpret_sentence(self, sentence):
        if type(sentence) == Clause:
            return [sentence]
        else:
            sentences = self.sentence_interpreters[type(sentence)](self, sentence, self.vars)
            result = []
            for s in sentences:
                if type(s) != Clause:
                    result.extend(self.interpret_sentence(s))
                else:
                    result.append(s)
            return result

    def register_core_sentence(self, id, sentence):
        self.core_map[id] = sentence

    def parse_output(self, output_lines, variable_map, ab_vars):
        if(output_lines[0] == 'sat'):
            output_values = []
            assignment = output_lines[1]
            for v in assignment.split(" "):
                var_num = int(v.strip("-"))-1
#                print var_num
                if var_num == -1 :
                    break
                elif var_num in self.ab_vars and not v.startswith("-"):
                    output_values.append(variable_map[var_num][3:])
            return output_values
        elif(output_lines[0] == 'unsat'):
            return None
        else:
            print "Uh oh! this one is neither SAT nor UNSAT?"
            print output_lines
Example #8
0
class SimpleYicesCnWrapper(SimpleYicesWrapper):
    
    def __init__(self, options={}):
        self.cnf = None
        self.outlines = None
        self.result = None
        self.get_valuation = False
        self.calculate_unsat_core = False
        self.solver_time = 0
        pidfile.seek(0)
        pidfile.write("0\n")
        self.options = options
        self.cn_k = 0
    
    def start(self, sd, **options):

        self.options.update(options)
        
        self.ab_vars = options.get('ab_vars', [])
        
        options['num_vars'] = sd.num_vars
        
        self.cnf = sd.cnf
        self.construct_cardinality_network(**options)
        self.cnf += [self.cnf_cn]

        self.num_vars = max([max(self.cn.vars), sd.num_vars])
        self.num_clauses = sd.num_clauses + len(self.clauses_cn)
        
#        if self.options.get('weighted',False):
#            header = "p wcnf %d %d\n" % (self.num_vars, self.num_clauses)
#            opts = ['-e', '-d', '-ms']
#        else:
        self.cnf += ["\n\n-%d 0\n" % self.cn.vars[self.options.get('max_card',1)]]
        self.num_clauses += 1 
        header = "p cnf %d %d\n" % (self.num_vars, self.num_clauses)
        opts = ['-e', '-d']

        with open(self.get_input_file_name(), "w") as f:
            f.write(header)
            for clauses in self.cnf:
                f.write(clauses)
                
        t0 = time.time()
        p = subprocess.Popen([YICES_EXECUTABLE_PATH] + opts, stdin=PIPE, stdout=PIPE)
        
        pidfile.seek(0)
        pidfile.write(str(p.pid) + "\n")
        out, unused_err = p.communicate(header + " " + " ".join(self.cnf))
        
        pidfile.seek(0)
        pidfile.write("0\n")
        t1 = time.time()
        self.solver_time = t1-t0
        self.outlines = out.strip().split("\n")
        self.result = self.parse_output(self.outlines)

    def start_again(self, sd, **options):
        return self.start(sd, **options)

    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card',1)+1,2)))
        n = k*int(math.ceil(float(len(self.ab_vars))/k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x, self.ab_vars)
            for i in xrange(options['num_vars']+1, options['num_vars']+(n-len(self.ab_vars))+1):    # +1: same reaseon as above
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                options['num_vars'] += 1
           
            self.cn = CardinalityNetwork(list(ab_vars_padded), next_var=options['num_vars']+1)
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in self.clauses_cn:
                self.cnf_cn += "\n" + " ".join(map(str, c+[0]))
Example #9
0
class YicesCnCnfEngine(YicesEngine):
        
    def __init__(self, options = {}):
        super(YicesCnCnfEngine, self).__init__(options)
        self.sentence_interpreters = {}
        self.variable_interpreters = {}
        self.sentence_interpreters.update(SENTENCE_INTERPRETERS_CN_CNF)
        self.variable_interpreters.update(VARIABLE_INTERPRETERS_CN_CNF)
        self.cn_k = None
        self.stats = {}

    def create_yices_code(self):
        code = []
        
#        print self.options.get("ab_vars", [])
        
        code.append("(reset)")
        if self.options.get('calculate_unsat_core', True) != False:
            code.append("(set-verbosity! 2)")
            code.append("(set-evidence! true)")
        self.construct_cardinality_network(**self.options)
        for v in self.description.get_variables():
            code.append(self.variable_interpreters[v.type](v))
        for s in self.description.get_sentences():
            if type(s) in self.sentence_interpreters:
                code.append(self.sentence_interpreters[type(s)](self, s, None))
        code.append(self.code_cn)
        
        code.append("(assert (not %s))" % self.mapping[self.cn.vars[self.options.get('max_card',1)]])
        
        self.stats['num_vars'] = len(self.description.get_variables())
        self.stats['num_rules'] = len(self.description.get_sentences()) + self.code_cn.count("\n") + 1
        
        code.append("(%s)" % self.options['check_cmd'])
        return "\n".join(code)

    def create_result(self, output_lines):
        output_lines = list(dropwhile(lambda x: x not in ['sat', 'unsat'], output_lines))
        result = super(YicesCnCnfEngine, self).create_result(output_lines)
        if result:
            return [k[3:] for k,v in result.values.iteritems() if  k.startswith("AB") and v is True]

    def construct_cardinality_network(self, **options):

        self.mapping = dict(enumerate(self.options.get('ab_vars', []), 1))
        self.ab_vars = self.mapping.keys()
        k = 2**int(math.ceil(math.log(options.get('max_card',1)+1,2)))
        n = k*int(math.ceil(float(len(self.ab_vars))/k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            
#            print "constructing network for k=%d" % k
            
            ab_vars_padded = map(lambda x: x, self.ab_vars)
            
            for i in xrange(max(self.ab_vars)+1, max(self.ab_vars)+(n-len(self.ab_vars))+1):
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                self.description.variables.append(Variable("cn_%d"%i, Variable.BOOLEAN, False))
                self.mapping[i] = "cn_%d"%i
                
#            print self.ab_vars
#            print ab_vars_padded
           
            self.cn = CardinalityNetwork(list(ab_vars_padded), next_var=max(ab_vars_padded)+1)
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)
            
#            print self.clauses_cn
#            print self.cn.vars
            
            for i in range(max(ab_vars_padded)+1, max(self.cn.vars)+1):
                self.description.variables.append(Variable("cn_%d"%i, Variable.BOOLEAN, None))
                self.mapping[i] = "cn_%d"%i

            self.code_cn = ""
            for clause in self.clauses_cn:
                self.code_cn += "\n(assert (or " + " ".join([("(not " if l < 0 else "") + self.mapping[abs(l)] + (")" if l < 0 else "") for l in clause]) + "))"
Example #10
0
class SCryptoMinisatSimpleEngine(SCryptoMinisatEngine):
    def __init__(self, options):
        super(SCryptoMinisatSimpleEngine, self).__init__(options)
        self.logfile = None  # open('scryptominisat.log', 'w')

    def start(self, description=None, **options):
        self.options.update(options)
        self.ab_vars = options.get('ab_vars')
        self.options['num_vars'] = description.num_vars
        self.cnf = "\n\n".join(description.cnf)
        self.max_out = options.get('max_out', max(self.ab_vars))
        self.start_time = time.time()
        return self.solve()

    def start_again(self, description, **options):
        self.options.update(options)
        self.ab_vars = options.get('ab_vars')
        self.options['num_vars'] = description.num_vars
        self.cnf = "\n\n".join(description.cnf)

        return self.solve()

    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card', 1) + 1, 2)))
        n = k * int(math.ceil(float(len(self.ab_vars)) / k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x, self.ab_vars)
            for i in xrange(options['num_vars'] + 1,
                            options['num_vars'] + (n - len(self.ab_vars)) +
                            1):  # +1: same reaseon as above
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                options['num_vars'] += 1

            self.cn = CardinalityNetwork(list(ab_vars_padded),
                                         next_var=options['num_vars'] + 1)
            #            print "CN input vars:", self.cn.vars
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)
            #            print "CN output vars:", self.cn.vars
            self.cnf_cn += "\n"
            for c in self.clauses_cn:
                self.cnf_cn += "\n" + " ".join(map(str, c + [0]))

    def map_back(self, v):
        return v


######## old: using the OddEvenMergeSortNetwork

# # the OEMS network must have a 2**n entries, so we need to pad with some auxiliary variables
# # and set them to 0 in the CNF
# size = len(ab_vars)
# size_new = 2**int(math.ceil(math.log(size,2)))
#
# self.cnf += "\n\n"
# ab_vars_padded = map(lambda x: x+1, ab_vars)    # +1 because the CNF vars start from 1 while we start from 0
# for i in xrange(max(ab_vars)+2, max(ab_vars)+(size_new-size)+2):    # +1: same reaseon as above
#     ab_vars_padded += [i]
#     self.cnf += "\n-%d 0" % i
#
# self.cnf += "\n"
# oems = OddEvenMergeSortNetwork(list(ab_vars_padded))
# sorter_clauses = oems.oddevenmergesort(range(len(ab_vars_padded)))
# for c in sorter_clauses:
#     self.cnf += "\n" + " ".join(map(str, c+[0]))
# self.cnf += "\n\n"
#
# self.cnf += "\nend"
# self.cnf += "\nminimize unary " + " ".join(map(str, oems.vars + [0]))

######## /old: using the OddEvenMergeSortNetwork
Example #11
0
class SCryptoMinisatEngine(Engine):
    """
    This is a high-level PicoSAT wrapper intended for the problem/description/engine/result mechanism in this 
    ``sat'' package. As such, it requires a description containing sentences and variables which will then 
    be converted to a CNF using the corresponding (registered) interpreters. For example, the ISCAS benchmark 
    framework contains sentences and interpreters for Boolean gates. 
    
    If the CNF has been constructed, it calls the low-level PicoSAT wrapper above. 
    """
    def __init__(self, options):
        super(SCryptoMinisatEngine, self).__init__(options)
        self.sentence_interpreters.update(SENTENCE_INTERPRETERS)
        self.variable_interpreters.update(VARIABLE_INTERPRETERS)
        self.cnf = ""
        self.cnf_cn = ""
        self.vars = {}
        self.cn_k = 0
        self.stats = {}
        self.time_map = None  # {}
        self.logfile = None  # open('scryptominisat.log', 'w')
        if self.options.get('cms-mod-variant', False):
            # HACK follows!!!
            global SCRYPTOMINISAT_PATH, SCRYPTOMINISAT_EXECUTABLE
            SCRYPTOMINISAT_PATH = os.path.dirname(os.path.abspath(
                __file__)) + '/../../lib/SCryptoMinisat-mod/SCryptoMinisat'
            SCRYPTOMINISAT_EXECUTABLE = SCRYPTOMINISAT_PATH + '/SCryptoMinisat'

    def start(self, description=None, **options):
        super(SCryptoMinisatEngine, self).start(description, **options)

        self.start_time = time.time()

        if not self.cnf:
            vars = sorted(self.description.get_variables(),
                          key=lambda x: not x.name.startswith("AB"))
            self.vars = TwoWayDict(
                dict((i, v.name) for i, v in enumerate(vars)))
            self.ab_vars = [
                i for i, n in self.vars.iteritems() if n.startswith("AB")
            ]

            # add clauses for the input/output variables which are constrained
            self.core_map = {}
            self.clauses = []
            for s in self.description.get_sentences():
                self.clauses.extend(self.sentence_interpreters[type(s)](
                    self, s, self.vars))
            for v in self.description.get_variables():
                if v.value is not None:
                    self.clauses.append(Clause([Literal(v.name, v.value)]))

            for c in self.clauses:
                self.cnf += "\n" + to_dimacs_clause(c, self.vars)

            self.stats['cnf_clauses'] = len(self.clauses)
            self.max_out = max(self.ab_vars) + 1

        return self.solve()

    def start_again(self, new_sentences, **options):
        super(SCryptoMinisatEngine, self).start_again(new_sentences, **options)
        clauses = []
        for s in new_sentences:
            clauses.extend(self.sentence_interpreters[type(s)](self, s,
                                                               self.vars))
        for c in clauses:
            self.cnf += "\n" + to_dimacs_clause(c, self.vars)
        self.stats['cnf_clauses'] += len(clauses)

        return self.solve()

    def solve(self):
        self.construct_cardinality_network(**self.options)

        cnf = "cnf\n" + self.cnf + self.cnf_cn
        cnf += "\n\n-%d 0\n" % self.cn.vars[self.options.get('max_card', 1)]
        cnf += "\nend"
        #        print self.max_out
        #        print self.options['max_card']
        cnf += "\noutput %d" % self.max_out
        #        cnf += "\nlimitsols 1000"

        if self.options.get('find_all_sols', False):
            cnf += "\nallsols"
        else:
            cnf += "\nsolve"

        self.stats['num_rules'] = self.stats.get(
            'cnf_clauses', 0) + self.stats.get('net_clauses', 0) + 1
        self.stats['num_vars'] = max(self.cn.vars)

        if self.options['async']:
            out = []
            result = []
            p = subprocess.Popen([SCRYPTOMINISAT_EXECUTABLE],
                                 stdout=PIPE,
                                 stdin=PIPE,
                                 close_fds=True)
            pidfile.seek(0)
            pidfile.write(str(p.pid) + "\n")

            t0 = time.time()
            #            print "SCMS started at  %.6f" % time.time()

            with open(SCRYPTOMINISAT_PATH + "/scryptominisat.in", 'w') as f:
                f.write(cnf)

            p.stdin.write(cnf)
            p.stdin.close()

            i = 0
            for line in p.stdout:
                i += 1
                out.append(line)
                if i % 2 == 0:
                    diag = self.parse_partial_output(out[-2:])
                    if diag:
                        result.append(frozenset(diag))
                        if self.time_map is not None:
                            self.time_map[frozenset(
                                diag)] = time.time() - self.start_time
                        if self.logfile is not None:
                            self.logfile.write(
                                "%12.3f: found diagnosis of size %5d: %s\n" %
                                (float(time.time() - self.start_time),
                                 len(diag), diag))
                            self.logfile.flush()
#                if line.strip() == "DONE" and self.logfile is not None:
#                    self.logfile.write("%12.3f: UNSAT\n" % float(time.time() - self.start_time))
#                    self.logfile.flush()

            pidfile.seek(0)
            pidfile.write("0\n")
            #            print "SCMS finished at %.6f" % time.time()
            t1 = time.time()
            self.solver_time = t1 - t0
            self.outlines = out
        else:
            with open(SCRYPTOMINISAT_PATH + "/scryptominisat.in", 'w') as f:
                f.write(cnf)

            t0 = time.time()
            p = subprocess.Popen([SCRYPTOMINISAT_EXECUTABLE],
                                 stdin=PIPE,
                                 stdout=PIPE)
            pidfile.seek(0)
            pidfile.write(str(p.pid) + "\n")
            out, unused_err = p.communicate(cnf)
            pidfile.seek(0)
            pidfile.write("0\n")
            t1 = time.time()
            self.solver_time = t1 - t0
            self.outlines = out.strip().split("\n")

        if self.options.get('find_all_sols',
                            False) and self.options.get('max_card', None) > 0:
            if self.options['async']:
                self.result = result
            else:
                self.result = self.parse_all_outputs(self.outlines)
        else:
            self.result = self.parse_output(self.outlines)


#        print self.result
        return self.result

    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card', 1) + 1, 2)))
        n = k * int(math.ceil(float(len(self.ab_vars)) / k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(
                lambda x: x + 1, self.ab_vars
            )  # +1 because the CNF vars start from 1 while we start from 0
            vars_padded = dict(self.vars)
            for i in xrange(
                    max(self.vars) + 2,
                    max(self.vars) + (n - len(self.ab_vars)) +
                    2):  # +1: same reaseon as above
                ab_vars_padded += [i]
                vars_padded[i] = 'temp'
                self.cnf_cn += "\n-%d 0" % i
                self.stats['net_clauses'] = self.stats.get('net_clauses',
                                                           0) + 1

            self.cn = CardinalityNetwork(list(ab_vars_padded),
                                         next_var=max(vars_padded) + 2)
            net_clauses = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in net_clauses:
                self.cnf_cn += "\n" + " ".join(map(str, c + [0]))
            self.stats['net_clauses'] = self.stats.get('net_clauses',
                                                       0) + len(net_clauses)

    def register_core_sentence(self, id, sentence):
        self.core_map[id] = sentence

    def parse_partial_output(self, output_lines):
        if output_lines[0].strip() == "SAT" and len(output_lines) > 1:
            output_values = []
            assignment = output_lines[-1]
            for v in assignment.split(" "):
                v = int(v)
                if v == 0:
                    break
                if v > 0:
                    output_values.append(self.map_back(v))
            return output_values
        else:
            return None

    def map_back(self, v):
        v = (v - 1) if v > 0 else (v + 1)  # compensate the DIMACS offset
        return self.vars[abs(v)][3:]

    def parse_output(self, output_lines):
        if output_lines[0].strip() == "UNSAT":
            return None
        else:
            if output_lines[-1].strip() == "DONE" or output_lines[0].strip(
            ) == "SAT":
                output_values = []
                assignment = output_lines[-2]
                for v in assignment.split(" "):
                    v = int(v)
                    if v == 0:
                        break
                    if v > 0:
                        output_values.append(self.map_back(v))
                return output_values
            elif output_lines[0].strip() == "SAT":
                return None
            else:
                print "Something went wrong with SCryptoMiniSAT, did not print UNSAT and DONE at the end."
                return None

    def parse_all_outputs(self, output_lines):
        if output_lines[0].strip() == "UNSAT":
            return None
        else:
            if output_lines[-1].strip() == "DONE":
                output_values = []
                for assignment in output_lines[1:-1:2]:
                    output_assignment = []
                    for v in assignment.split(" "):
                        v = int(v)
                        if v == 0:
                            break
                        if v > 0:
                            output_assignment.append(self.map_back(v))
                    output_values.append(frozenset(output_assignment))
                return output_values
            elif output_lines[0].strip() == "SAT":
                return None
            else:
                print "Something went wrong with SCryptoMiniSAT, did not print UNSAT and DONE at the end."
                return None
Example #12
0
class SCryptoMinisatSimpleEngine(SCryptoMinisatEngine):
    
    def __init__(self, options):
        super(SCryptoMinisatSimpleEngine, self).__init__(options)
        self.logfile = None # open('scryptominisat.log', 'w')
    
    def start(self, description=None, **options):
        self.options.update(options)
        self.ab_vars = options.get('ab_vars')
        self.options['num_vars'] = description.num_vars
        self.cnf = "\n\n".join(description.cnf)
        self.max_out = options.get('max_out', max(self.ab_vars))
        self.start_time = time.time()
        return self.solve()

    def start_again(self, description, **options):
        self.options.update(options)
        self.ab_vars = options.get('ab_vars')
        self.options['num_vars'] = description.num_vars
        self.cnf = "\n\n".join(description.cnf)
            
        return self.solve()

    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card',1)+1,2)))
        n = k*int(math.ceil(float(len(self.ab_vars))/k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x, self.ab_vars)
            for i in xrange(options['num_vars']+1, options['num_vars']+(n-len(self.ab_vars))+1):    # +1: same reaseon as above
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                options['num_vars'] += 1
           
            self.cn = CardinalityNetwork(list(ab_vars_padded), next_var=options['num_vars']+1)
#            print "CN input vars:", self.cn.vars
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)
#            print "CN output vars:", self.cn.vars
            self.cnf_cn += "\n"
            for c in self.clauses_cn:
                self.cnf_cn += "\n" + " ".join(map(str, c+[0]))

    def map_back(self, v):
        return v

######## old: using the OddEvenMergeSortNetwork

# # the OEMS network must have a 2**n entries, so we need to pad with some auxiliary variables
# # and set them to 0 in the CNF
# size = len(ab_vars)
# size_new = 2**int(math.ceil(math.log(size,2)))
# 
# self.cnf += "\n\n"
# ab_vars_padded = map(lambda x: x+1, ab_vars)    # +1 because the CNF vars start from 1 while we start from 0 
# for i in xrange(max(ab_vars)+2, max(ab_vars)+(size_new-size)+2):    # +1: same reaseon as above
#     ab_vars_padded += [i]
#     self.cnf += "\n-%d 0" % i
# 
# self.cnf += "\n"
# oems = OddEvenMergeSortNetwork(list(ab_vars_padded))
# sorter_clauses = oems.oddevenmergesort(range(len(ab_vars_padded)))
# for c in sorter_clauses:
#     self.cnf += "\n" + " ".join(map(str, c+[0]))
# self.cnf += "\n\n"
#     
# self.cnf += "\nend"
# self.cnf += "\nminimize unary " + " ".join(map(str, oems.vars + [0]))

######## /old: using the OddEvenMergeSortNetwork
Example #13
0
class SCryptoMinisatEngine(Engine):
    
    """
    This is a high-level PicoSAT wrapper intended for the problem/description/engine/result mechanism in this 
    ``sat'' package. As such, it requires a description containing sentences and variables which will then 
    be converted to a CNF using the corresponding (registered) interpreters. For example, the ISCAS benchmark 
    framework contains sentences and interpreters for Boolean gates. 
    
    If the CNF has been constructed, it calls the low-level PicoSAT wrapper above. 
    """
    
    def __init__(self, options):
        super(SCryptoMinisatEngine, self).__init__(options)
        self.sentence_interpreters.update(SENTENCE_INTERPRETERS)
        self.variable_interpreters.update(VARIABLE_INTERPRETERS)
        self.cnf = ""
        self.cnf_cn = ""
        self.vars = {}
        self.cn_k = 0
        self.stats = {}
        self.time_map = None # {}
        self.logfile = None # open('scryptominisat.log', 'w')
        if self.options.get('cms-mod-variant',False):
            # HACK follows!!!
            global SCRYPTOMINISAT_PATH, SCRYPTOMINISAT_EXECUTABLE
            SCRYPTOMINISAT_PATH = os.path.dirname(os.path.abspath(__file__)) + '/../../lib/SCryptoMinisat-mod/SCryptoMinisat'
            SCRYPTOMINISAT_EXECUTABLE  = SCRYPTOMINISAT_PATH + '/SCryptoMinisat'

    
    def start(self, description=None, **options):
        super(SCryptoMinisatEngine, self).start(description, **options)

        self.start_time = time.time()
        
        if not self.cnf:
            vars = sorted(self.description.get_variables(), key=lambda x: not x.name.startswith("AB"))
            self.vars = TwoWayDict(dict((i, v.name) for i,v in enumerate(vars)))
            self.ab_vars = [i for i,n in self.vars.iteritems() if n.startswith("AB")]

            # add clauses for the input/output variables which are constrained
            self.core_map = {}
            self.clauses = []
            for s in self.description.get_sentences():
                self.clauses.extend(self.sentence_interpreters[type(s)](self, s, self.vars))
            for v in self.description.get_variables():
                if v.value is not None:
                    self.clauses.append(Clause([Literal(v.name, v.value)])) 
            
            for c in self.clauses:
                self.cnf += "\n" + to_dimacs_clause(c, self.vars)
            
            self.stats['cnf_clauses'] = len(self.clauses)
            self.max_out = max(self.ab_vars) + 1
            
        return self.solve()

    def start_again(self, new_sentences, **options):
        super(SCryptoMinisatEngine, self).start_again(new_sentences, **options)
        clauses = []
        for s in new_sentences:
            clauses.extend(self.sentence_interpreters[type(s)](self, s, self.vars))
        for c in clauses:
            self.cnf += "\n" + to_dimacs_clause(c, self.vars)
        self.stats['cnf_clauses'] += len(clauses)
            
        return self.solve()

    def solve(self):
        self.construct_cardinality_network(**self.options)
        
        cnf  = "cnf\n" + self.cnf + self.cnf_cn
        cnf += "\n\n-%d 0\n" % self.cn.vars[self.options.get('max_card',1)] 
        cnf += "\nend"
#        print self.max_out
#        print self.options['max_card']
        cnf += "\noutput %d" % self.max_out
#        cnf += "\nlimitsols 1000"
        
        if self.options.get('find_all_sols', False):
            cnf += "\nallsols"
        else:
            cnf += "\nsolve"

        self.stats['num_rules'] = self.stats.get('cnf_clauses',0) + self.stats.get('net_clauses',0) + 1
        self.stats['num_vars']  = max(self.cn.vars)

        if self.options['async']:        
            out = []
            result = []
            p = subprocess.Popen([SCRYPTOMINISAT_EXECUTABLE], stdout=PIPE, stdin=PIPE, close_fds=True)
            pidfile.seek(0)
            pidfile.write(str(p.pid) + "\n")
    
            t0 = time.time()
#            print "SCMS started at  %.6f" % time.time()
            
            with open(SCRYPTOMINISAT_PATH + "/scryptominisat.in", 'w') as f:
                f.write(cnf)
            
            p.stdin.write(cnf)
            p.stdin.close()
            
            i = 0
            for line in p.stdout:
                i += 1
                out.append(line)
                if i % 2 == 0:
                    diag = self.parse_partial_output(out[-2:])
                    if diag:
                        result.append(frozenset(diag))
                        if self.time_map is not None:
                            self.time_map[frozenset(diag)] = time.time() - self.start_time
                        if self.logfile is not None:
                            self.logfile.write("%12.3f: found diagnosis of size %5d: %s\n" % (float(time.time() - self.start_time), len(diag), diag))
                            self.logfile.flush()
#                if line.strip() == "DONE" and self.logfile is not None:
#                    self.logfile.write("%12.3f: UNSAT\n" % float(time.time() - self.start_time))
#                    self.logfile.flush()

            pidfile.seek(0)
            pidfile.write("0\n")
#            print "SCMS finished at %.6f" % time.time()
            t1 = time.time()
            self.solver_time = t1-t0
            self.outlines = out 
        else:
            with open(SCRYPTOMINISAT_PATH + "/scryptominisat.in", 'w') as f:
                f.write(cnf)
                
            t0 = time.time()
            p = subprocess.Popen([SCRYPTOMINISAT_EXECUTABLE], stdin=PIPE, stdout=PIPE)            
            pidfile.seek(0)
            pidfile.write(str(p.pid) + "\n")
            out, unused_err = p.communicate(cnf)
            pidfile.seek(0)
            pidfile.write("0\n")
            t1 = time.time()
            self.solver_time = t1-t0
            self.outlines = out.strip().split("\n")
        
        if self.options.get('find_all_sols', False) and self.options.get('max_card', None) > 0:
            if self.options['async']:
                self.result = result
            else:
                self.result = self.parse_all_outputs(self.outlines)
        else:
            self.result = self.parse_output(self.outlines)
#        print self.result
        return self.result

    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card',1)+1,2)))
        n = k*int(math.ceil(float(len(self.ab_vars))/k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x+1, self.ab_vars)    # +1 because the CNF vars start from 1 while we start from 0
            vars_padded = dict(self.vars) 
            for i in xrange(max(self.vars)+2, max(self.vars)+(n-len(self.ab_vars))+2):    # +1: same reaseon as above
                ab_vars_padded += [i]
                vars_padded[i] = 'temp'
                self.cnf_cn += "\n-%d 0" % i
                self.stats['net_clauses'] = self.stats.get('net_clauses',0) + 1
            
            self.cn = CardinalityNetwork(list(ab_vars_padded), next_var=max(vars_padded)+2)
            net_clauses = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in net_clauses:
                self.cnf_cn += "\n" + " ".join(map(str, c+[0]))
            self.stats['net_clauses'] = self.stats.get('net_clauses',0) + len(net_clauses)

    def register_core_sentence(self, id, sentence):
        self.core_map[id] = sentence

    def parse_partial_output(self, output_lines):
        if output_lines[0].strip() == "SAT" and len(output_lines) > 1:
            output_values = []
            assignment = output_lines[-1]
            for v in assignment.split(" "):
                v = int(v)
                if v == 0:
                    break
                if v > 0:
                    output_values.append(self.map_back(v))
            return output_values
        else:
            return None
            
    def map_back(self, v):
        v = (v - 1) if v > 0 else (v + 1) # compensate the DIMACS offset
        return self.vars[abs(v)][3:]

    def parse_output(self, output_lines):
        if output_lines[0].strip() == "UNSAT":
            return None
        else:
            if output_lines[-1].strip() == "DONE" or output_lines[0].strip() == "SAT":
                output_values = []
                assignment = output_lines[-2]
                for v in assignment.split(" "):
                    v = int(v)
                    if v == 0:
                        break
                    if v > 0:
                        output_values.append(self.map_back(v))
                return output_values
            elif output_lines[0].strip() == "SAT":
                return None
            else:
                print "Something went wrong with SCryptoMiniSAT, did not print UNSAT and DONE at the end."
                return None

    def parse_all_outputs(self, output_lines):
        if output_lines[0].strip() == "UNSAT":
            return None
        else:
            if output_lines[-1].strip() == "DONE":
                output_values = []
                for assignment in output_lines[1:-1:2]:
                    output_assignment = []
                    for v in assignment.split(" "):
                        v = int(v)
                        if v == 0:
                            break
                        if v > 0:
                            output_assignment.append(self.map_back(v))
                    output_values.append(frozenset(output_assignment))
                return output_values
            elif output_lines[0].strip() == "SAT":
                return None
            else:
                print "Something went wrong with SCryptoMiniSAT, did not print UNSAT and DONE at the end."
                return None
Example #14
0
class YicesCnEngine(Engine):
    def __init__(self, options):
        super(YicesCnEngine, self).__init__(options)

        self.sentence_interpreters.update(SENTENCE_INTERPRETERS_CN)

        self.cnf = ""
        self.cnf_cn = ""
        self.vars = {}
        self.cn_k = 0
        self.stats = {}

    def to_dimacs_literal(self, literal, variable_map):
        if literal.sign == True:
            return str(variable_map.get_key(literal.name) + 1)
        else:
            return "-" + str(variable_map.get_key(literal.name) + 1)

    def to_dimacs_clause(self, clause, variable_map):
        literals = map(lambda l: self.to_dimacs_literal(l, variable_map),
                       clause.literals)
        return " ".join(literals) + " 0"

    def start_again(self, new_sentences, **options):
        super(YicesCnEngine, self).start_again(new_sentences, **options)
        clauses = self.interpret_sentences(new_sentences)
        for c in clauses:
            self.cnf += "\n" + self.to_dimacs_clause(c, self.vars)
        self.stats['cnf_clauses'] += len(clauses)

        self.construct_cardinality_network(**options)

        self.stats['num_rules'] = self.stats.get(
            'cnf_clauses', 0) + self.stats.get('net_clauses', 0) + 1
        self.stats['num_vars'] = max(self.cn.vars)

        #        cnf  = "p cnf %d %d\n" % (self.stats['num_vars'], self.stats['num_rules']) + self.cnf + self.cnf_cn
        cnf = self.cnf + self.cnf_cn
        cnf += "\n\n-%d 0\n" % self.cn.vars[options.get('max_card', 1)]

        p = SimpleYicesWrapper()
        p.start(
            SimpleDescription(cnf, self.stats['num_vars'],
                              self.stats['num_rules']))
        self.result = self.parse_output(p.outlines, self.vars, self.ab_vars)
        return self.result

    def start(self, description=None, **options):
        super(YicesCnEngine, self).start(description, **options)

        if not self.cnf:
            vars = sorted(self.description.get_variables(),
                          key=lambda x: not x.name.startswith("AB"))
            self.vars = TwoWayDict(
                dict((i, v.name) for i, v in enumerate(vars)))
            self.ab_vars = [
                i for i, n in self.vars.iteritems() if n.startswith("AB")
            ]
            sentences = self.description.get_sentences()
            for v in self.description.get_variables():
                if v.value is not None:
                    sentences.append(Clause([Literal(v.name, v.value)]))
            self.core_map = {}
            self.clauses = self.interpret_sentences(sentences)

            for c in self.clauses:
                self.cnf += "\n" + self.to_dimacs_clause(c, self.vars)

            self.stats['cnf_clauses'] = len(self.clauses)

        self.construct_cardinality_network(**options)

        self.stats['num_rules'] = self.stats.get(
            'cnf_clauses', 0) + self.stats.get('net_clauses', 0) + 1
        self.stats['num_vars'] = max(self.cn.vars)

        #        cnf  = "p cnf %d %d\n" % (self.stats['num_vars'], self.stats['num_rules']) + self.cnf + self.cnf_cn
        cnf = self.cnf + self.cnf_cn
        cnf += "\n\n-%d 0\n" % self.cn.vars[options.get('max_card', 1)]

        p = SimpleYicesWrapper()
        p.start(
            SimpleDescription(cnf, self.stats['num_vars'],
                              self.stats['num_rules']))

        self.result = self.parse_output(p.outlines, self.vars, self.ab_vars)
        return self.result

    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card', 1) + 1, 2)))
        n = k * int(math.ceil(float(len(self.ab_vars)) / k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(
                lambda x: x + 1, self.ab_vars
            )  # +1 because the CNF vars start from 1 while we start from 0
            vars_padded = dict(self.vars)
            for i in xrange(
                    max(self.vars) + 2,
                    max(self.vars) + (n - len(self.ab_vars)) +
                    2):  # +1: same reaseon as above
                ab_vars_padded += [i]
                vars_padded[i] = 'temp'
                self.cnf_cn += "\n-%d 0" % i
                self.stats['net_clauses'] = self.stats.get('net_clauses',
                                                           0) + 1

            self.cn = CardinalityNetwork(list(ab_vars_padded),
                                         next_var=max(vars_padded) + 2)
            #            print "constructing CN in yices"
            net_clauses = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in net_clauses:
                self.cnf_cn += "\n" + " ".join(map(str, c + [0]))
            self.stats['net_clauses'] = self.stats.get('net_clauses',
                                                       0) + len(net_clauses)

    def interpret_sentences(self, sentences):
        interpreted_sentences = []
        for s in sentences:
            if type(s) in self.sentence_interpreters:
                interpreted_sentences.extend(self.interpret_sentence(s))
            else:
                interpreted_sentences.append(s)
        return interpreted_sentences

    def interpret_sentence(self, sentence):
        if type(sentence) == Clause:
            return [sentence]
        else:
            sentences = self.sentence_interpreters[type(sentence)](self,
                                                                   sentence,
                                                                   self.vars)
            result = []
            for s in sentences:
                if type(s) != Clause:
                    result.extend(self.interpret_sentence(s))
                else:
                    result.append(s)
            return result

    def register_core_sentence(self, id, sentence):
        self.core_map[id] = sentence

    def parse_output(self, output_lines, variable_map, ab_vars):
        if (output_lines[0] == 'sat'):
            output_values = []
            assignment = output_lines[1]
            for v in assignment.split(" "):
                var_num = int(v.strip("-")) - 1
                #                print var_num
                if var_num == -1:
                    break
                elif var_num in self.ab_vars and not v.startswith("-"):
                    output_values.append(variable_map[var_num][3:])
            return output_values
        elif (output_lines[0] == 'unsat'):
            return None
        else:
            print "Uh oh! this one is neither SAT nor UNSAT?"
            print output_lines
Example #15
0
class SimpleYicesCnWrapper(SimpleYicesWrapper):
    def __init__(self, options={}):
        self.cnf = None
        self.outlines = None
        self.result = None
        self.get_valuation = False
        self.calculate_unsat_core = False
        self.solver_time = 0
        pidfile.seek(0)
        pidfile.write("0\n")
        self.options = options
        self.cn_k = 0

    def start(self, sd, **options):

        self.options.update(options)

        self.ab_vars = options.get('ab_vars', [])

        options['num_vars'] = sd.num_vars

        self.cnf = sd.cnf
        self.construct_cardinality_network(**options)
        self.cnf += [self.cnf_cn]

        self.num_vars = max([max(self.cn.vars), sd.num_vars])
        self.num_clauses = sd.num_clauses + len(self.clauses_cn)

        #        if self.options.get('weighted',False):
        #            header = "p wcnf %d %d\n" % (self.num_vars, self.num_clauses)
        #            opts = ['-e', '-d', '-ms']
        #        else:
        self.cnf += [
            "\n\n-%d 0\n" % self.cn.vars[self.options.get('max_card', 1)]
        ]
        self.num_clauses += 1
        header = "p cnf %d %d\n" % (self.num_vars, self.num_clauses)
        opts = ['-e', '-d']

        with open(self.get_input_file_name(), "w") as f:
            f.write(header)
            for clauses in self.cnf:
                f.write(clauses)

        t0 = time.time()
        p = subprocess.Popen([YICES_EXECUTABLE_PATH] + opts,
                             stdin=PIPE,
                             stdout=PIPE)

        pidfile.seek(0)
        pidfile.write(str(p.pid) + "\n")
        out, unused_err = p.communicate(header + " " + " ".join(self.cnf))

        pidfile.seek(0)
        pidfile.write("0\n")
        t1 = time.time()
        self.solver_time = t1 - t0
        self.outlines = out.strip().split("\n")
        self.result = self.parse_output(self.outlines)

    def start_again(self, sd, **options):
        return self.start(sd, **options)

    def construct_cardinality_network(self, **options):

        k = 2**int(math.ceil(math.log(options.get('max_card', 1) + 1, 2)))
        n = k * int(math.ceil(float(len(self.ab_vars)) / k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"
            ab_vars_padded = map(lambda x: x, self.ab_vars)
            for i in xrange(options['num_vars'] + 1,
                            options['num_vars'] + (n - len(self.ab_vars)) +
                            1):  # +1: same reaseon as above
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                options['num_vars'] += 1

            self.cn = CardinalityNetwork(list(ab_vars_padded),
                                         next_var=options['num_vars'] + 1)
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)
            self.cnf_cn += "\n"
            for c in self.clauses_cn:
                self.cnf_cn += "\n" + " ".join(map(str, c + [0]))
Example #16
0
class YicesCnCnfEngine(YicesEngine):
    def __init__(self, options={}):
        super(YicesCnCnfEngine, self).__init__(options)
        self.sentence_interpreters = {}
        self.variable_interpreters = {}
        self.sentence_interpreters.update(SENTENCE_INTERPRETERS_CN_CNF)
        self.variable_interpreters.update(VARIABLE_INTERPRETERS_CN_CNF)
        self.cn_k = None
        self.stats = {}

    def create_yices_code(self):
        code = []

        #        print self.options.get("ab_vars", [])

        code.append("(reset)")
        if self.options.get('calculate_unsat_core', True) != False:
            code.append("(set-verbosity! 2)")
            code.append("(set-evidence! true)")
        self.construct_cardinality_network(**self.options)
        for v in self.description.get_variables():
            code.append(self.variable_interpreters[v.type](v))
        for s in self.description.get_sentences():
            if type(s) in self.sentence_interpreters:
                code.append(self.sentence_interpreters[type(s)](self, s, None))
        code.append(self.code_cn)

        code.append(
            "(assert (not %s))" %
            self.mapping[self.cn.vars[self.options.get('max_card', 1)]])

        self.stats['num_vars'] = len(self.description.get_variables())
        self.stats['num_rules'] = len(
            self.description.get_sentences()) + self.code_cn.count("\n") + 1

        code.append("(%s)" % self.options['check_cmd'])
        return "\n".join(code)

    def create_result(self, output_lines):
        output_lines = list(
            dropwhile(lambda x: x not in ['sat', 'unsat'], output_lines))
        result = super(YicesCnCnfEngine, self).create_result(output_lines)
        if result:
            return [
                k[3:] for k, v in result.values.iteritems()
                if k.startswith("AB") and v is True
            ]

    def construct_cardinality_network(self, **options):

        self.mapping = dict(enumerate(self.options.get('ab_vars', []), 1))
        self.ab_vars = self.mapping.keys()
        k = 2**int(math.ceil(math.log(options.get('max_card', 1) + 1, 2)))
        n = k * int(math.ceil(float(len(self.ab_vars)) / k))

        if self.cn_k != k:
            self.cn_k = k
            self.cnf_cn = "\n"

            #            print "constructing network for k=%d" % k

            ab_vars_padded = map(lambda x: x, self.ab_vars)

            for i in xrange(
                    max(self.ab_vars) + 1,
                    max(self.ab_vars) + (n - len(self.ab_vars)) + 1):
                ab_vars_padded += [i]
                self.cnf_cn += "\n-%d 0" % i
                self.description.variables.append(
                    Variable("cn_%d" % i, Variable.BOOLEAN, False))
                self.mapping[i] = "cn_%d" % i


#            print self.ab_vars
#            print ab_vars_padded

            self.cn = CardinalityNetwork(list(ab_vars_padded),
                                         next_var=max(ab_vars_padded) + 1)
            self.clauses_cn = self.cn.card(range(len(ab_vars_padded)), k)

            #            print self.clauses_cn
            #            print self.cn.vars

            for i in range(max(ab_vars_padded) + 1, max(self.cn.vars) + 1):
                self.description.variables.append(
                    Variable("cn_%d" % i, Variable.BOOLEAN, None))
                self.mapping[i] = "cn_%d" % i

            self.code_cn = ""
            for clause in self.clauses_cn:
                self.code_cn += "\n(assert (or " + " ".join(
                    [("(not " if l < 0 else "") + self.mapping[abs(l)] +
                     (")" if l < 0 else "") for l in clause]) + "))"