def __init__(self, clause_list, model): self.clauses = [ Clause(cl, model, _id) for (_id, cl) in enumerate(clause_list, 0) ] self.learnt_clauses = [] self.watched_var_dict = self._make_dict() self._make_dict()
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 read_from_file(cls, filepath): """ Create an instance of Sentences from an input file. This file format is given by the professor for this class. Args: filepath <str>: the filepath to the input file. Returns: <sentences.Sentences>: an instance of the Sentences class with the given clauses in the input file. """ clauses = [] f = open(filepath) # First read in the clauses for line in f: clause = [] if line[0] == '0': break else: line = line.strip().split(' ') for l in line: clause.append(Atom(l)) clauses.append(Clause(clause)) # Then read in the rest of the input file for the translation rest_of_input = [] for line in f: rest_of_input.append(line) return cls(clauses, rest_of_input)
def start(self, description=None, **options): super(PicoSatEngine, self).start(description, **options) if not self.cnf: self.vars = TwoWayDict( dict((i, v.name) for i, v in enumerate(self.description.get_variables()))) # add clauses for the input/output variables which are constrained 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) self.cnf = "p cnf %d %d" % (max(self.vars.keys()) + 1, len(self.clauses)) for c in self.clauses: self.cnf += "\n" + to_dimacs_clause(c, self.vars) # print self.cnf p = PicoSatWrapper() p.start(self.cnf, calculate_unsat_core=True) # print "\n".join(outlines) self.result = self.parse_output(p.outlines, self.vars, p.get_core_file_name()) return self.result
def test_unit(self: TestClause): clause = Clause([-6, 5, -4, 3, -2, 1]) a1 = Assignment(set([1, 2, 3, 4, 5, 6])) a1.add_assignment(0, 6, 1, None) clause.assign(a1) a1.add_assignment(1, 5, 0, None) a1.add_assignment(2, 3, 0, None) a1.add_assignment(2, 4, 1, None) a1.add_assignment(2, 1, 0, None) clause.assign(a1) self.assertEqual(clause.get_state(a1), (Clause.UNIT, 2, 2)) self.assertEqual(clause.get_assigned_vars(a1), [6, 5, 4, 3, 1])
def _add_base_clause(self: Formula, clause: List[int]) -> None: """Add a clause to the formula, only during initialization. """ clause_object = Clause(clause) self.formula.append(clause_object) head_var, tail_var = clause_object.get_head_tail_var() if head_var not in self.variable_clauses: self.variable_clauses[head_var] = set() self.variable_clauses[head_var].add(clause_object) if tail_var not in self.variable_clauses: self.variable_clauses[tail_var] = set() self.variable_clauses[tail_var].add(clause_object) if len(clause) == 1: self.unit_clauses.add(clause_object)
def create_yices_code(self): code = [] for v in self.description.get_variables(): self.vars[v.name] = self.next_var self.next_var += 1 if v.value is not None: code.append( self.to_dimacs_clause( Clause([Literal(v.name, v.value)], weight=self.MAX_WEIGHT + 1), self.vars)) for s in self.description.get_sentences(): for c in self.sentence_interpreters[type(s)](self, s, None): code.append(self.to_dimacs_clause(c, self.vars)) return len(code), "\n".join(code)
def add_clause(self: Formula, clause: List[int]) -> None: """Add a clause to the formula after initialization. :param clause: a list of `Literal`s that are contained in the clause; each variable must appear in `clause` at most once. `clause` cannot contain literals in variables not already present in the representation. """ clause_object = Clause(clause) clause_object.assign(self.assignment) self.formula.append(clause_object) # update mutation history and state history old_head_var, old_tail_var = clause_object.get_head_tail_var() was_valid = False was_unsat = len(clause) == 0 for d in range(0, self.decision_level + 1): clause_object.assign_decision_level(self.assignment, d) state, head_var, tail_var = clause_object.get_state( self.assignment.get_assignment_at_level(d)) if head_var != old_head_var or tail_var != old_tail_var: self.mutation_history[d].add(clause_object) # can actually be commented out since we never make # decisions while the formila is valid or unsat was_valid = was_valid or state == Clause.SATISFIED was_unsat = was_unsat or state == Clause.UNSATISFIED if self.state_history[d] == Formula.SATISFIED and not was_valid: self.state_history[d] = Formula.UNRESOLVED if was_unsat: self.state_history[d] = Formula.UNSATISFIED # update current state state, head_var, tail_var = clause_object.get_state(self.assignment) if state == Clause.UNRESOLVED or state == Clause.UNIT: if head_var not in self.variable_clauses: self.variable_clauses[head_var] = set() self.variable_clauses[head_var].add(clause_object) if tail_var not in self.variable_clauses: self.variable_clauses[tail_var] = set() self.variable_clauses[tail_var].add(clause_object) # update unit clauses if state == Clause.UNIT: self.unit_clauses.add(clause_object) # update unsat clauses if state == Clause.UNSATISFIED: self.unsat_clauses.add(clause_object)
def read_input(file): cnf = [] f = open(file, "r") clause_id = 0 for line in f: if len(line) < 3: continue if line[0] in ["c", "p", "%"]: continue # props = strip(line)[:-1].split() # get rid of the trailing 0 props = (line[:-2] ).split() # for lines, last character is newline character. clause = Clause(clause_id, props) cnf.append(clause) clause_id += 1 return Form(cnf)
def resolve(self, clause1, clause2): # Store that these two clauses have been resolved self.resolvedClauses.append(set([clause1, clause2])) # Get the resolution of the two clauses newClauseLiterals = self.getResolution(clause1, clause2) # Create a new Clause object newClause = Clause(' '.join(newClauseLiterals), len(self.clauses) + 1) self.clauses.append(newClause) printedClause = ' '.join(newClauseLiterals) if len( newClause.literals) > 0 else 'False' # Print the resolution info self.printLine(newClause.id, printedClause, True, clause1.id, clause2.id) return len(newClause.literals) == 0
def test_backtrack(self: TestClause): clause = Clause([-6, 5, -4, 3, -2, 1]) a1 = Assignment(set([1, 2, 3, 4, 5, 6])) a1.add_assignment(0, 5, 0, None) a1.add_assignment(1, 3, 0, None) clause.assign(a1) a1.add_assignment(1, 6, 1, None) a1.add_assignment(1, 4, 1, None) a1.add_assignment(2, 1, 0, None) a1.add_assignment(2, 2, 1, None) clause.assign(a1) self.assertEqual(clause.get_state(a1), (Clause.UNSATISFIED, 1, 1)) self.assertEqual(clause.get_assigned_vars(a1), [6, 5, 4, 3, 2, 1]) clause.backtrack(1) a1.backtrack(1) self.assertEqual(clause.get_state(a1), (Clause.UNRESOLVED, 2, 1)) self.assertEqual(clause.get_assigned_vars(a1), [6, 5, 4, 3]) clause.backtrack(0) a1.backtrack(0) self.assertEqual(clause.get_state(a1), (Clause.UNRESOLVED, 6, 1)) self.assertEqual(clause.get_assigned_vars(a1), [5])
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 generate(self): num_of_var = self.num_of_var + self.get_variation(self.num_of_var) num_of_clause = self.num_of_clause + self.get_variation( self.num_of_clause) clause_list = list() for i in range(num_of_clause): num_of_var_per_clause = self.num_of_var_per_clause + self.get_variation( self.num_of_var_per_clause) var_list = list() for j in range(num_of_var_per_clause): signal = 1 if rd() > 0.5: signal = -1 var_str = str(int(signal * round(num_of_var * rd() + 1))) var = Variable(var_str) var_list.append(var) clause = Clause(var_list) clause_list.append(clause) cnf = Cnf(clause_list) return cnf
def write_true_belief_chapter(start_state, oracle, location, agent_ids, all_agents, questions=None): """ Creates list of clauses that constitute a true belief task. agent_ids: list that gives indices of agents in container. should be length 2. all_agents: list of all agents container: container to which the object is moved question: one of ['memory', 'reality', 'belief', 'search', None] if None, then pick randomly Warning: clauses will advance that state of the simulation, should clauses should be appended in order. """ a1, a2 = all_agents[agent_ids[0]], all_agents[agent_ids[1]] agent_ids = [aid + 1 for aid in agent_ids] # Pick random object at location obj = np.random.choice(oracle.get_objects_at_location(location)) container_1 = oracle.get_object_container(obj) # Pick random container in locations container_candidates = oracle.get_containers(location)[:] container_candidates.remove(container_1) container_2 = np.random.choice(container_candidates) chapter = [] # Move agents into location if oracle.get_location(a1) == location: chapter.extend( [Clause([agent_ids[0]], LocationAction(oracle, (a1, location)))]) else: chapter.extend( [Clause([agent_ids[0]], EnterAction(oracle, (a1, location)))]) if oracle.get_location(a2) == location: chapter.extend( [Clause(agent_ids, LocationAction(oracle, (a2, location)))]) else: chapter.extend( [Clause(agent_ids, EnterAction(oracle, (a2, location), [a1]))]) chapter.extend([ Clause(agent_ids, ObjectLocAction(oracle, obj, [a1, a2])), Clause(agent_ids, MoveAction(oracle, (a1, obj, container_2), [a2])), ]) for question in questions: chapter.append( sample_question(start_state, oracle, a1, a2, obj, question)) return chapter
def test_init(self: TestClause): clause = Clause([-6, 5, -4, 3, -2, 1]) self.assertEqual(clause.get_head_tail_var(), (6, 1))
def build_formula(): b1 = Bool("b1") b2 = Bool("b2") b3 = Bool("b3") b4 = Bool("b4") b5 = Bool("b5") b6 = Bool("b6") b7 = Bool("b7") b8 = Bool("b8") b9 = Bool("b9") b10 = Bool("b10") b11 = Bool("b11") b12 = Bool("b12") b13 = Bool("b13") b14 = Bool("b14") b15 = Bool("b15") b16 = Bool("b16") lit_b1 = Literal(b1, negated=False) lit_b2 = Literal(b2, negated=False) lit_b3 = Literal(b3, negated=False) lit_b4 = Literal(b4, negated=False) lit_b5 = Literal(b5, negated=False) lit_b6 = Literal(b6, negated=False) lit_b7 = Literal(b7, negated=False) lit_b8 = Literal(b8, negated=False) lit_b9 = Literal(b9, negated=False) lit_b10 = Literal(b10, negated=False) lit_b11 = Literal(b11, negated=False) lit_b12 = Literal(b12, negated=False) lit_b13 = Literal(b13, negated=False) lit_b14 = Literal(b14, negated=False) lit_b15 = Literal(b15, negated=False) lit_b16 = Literal(b16, negated=False) lit_b16_bar = Literal(b16, negated=True) lit_b15_bar = Literal(b15, negated=True) lit_b14_bar = Literal(b14, negated=True) lit_b11_bar = Literal(b11, negated=True) lit_b10_bar = Literal(b10, negated=True) lit_b9_bar = Literal(b9, negated=True) lit_b8_bar = Literal(b8, negated=True) lit_b7_bar = Literal(b7, negated=True) lit_b6_bar = Literal(b6, negated=True) lit_b5_bar = Literal(b5, negated=True) lit_b4_bar = Literal(b4, negated=True) lit_b2_bar = Literal(b2, negated=True) clause0 = Clause([lit_b1, lit_b2]) clause1 = Clause([lit_b2_bar, lit_b4_bar]) clause2 = Clause([lit_b3, lit_b4]) clause3 = Clause([lit_b4_bar, lit_b5_bar]) clause4 = Clause([lit_b5, lit_b6_bar]) clause5 = Clause([lit_b6, lit_b7_bar]) clause6 = Clause([lit_b6, lit_b7]) clause7 = Clause([lit_b7, lit_b16_bar]) clause8 = Clause([lit_b8, lit_b9_bar]) clause9 = Clause([lit_b8_bar, lit_b14_bar]) clause10 = Clause([lit_b9, lit_b10]) clause11 = Clause([lit_b9, lit_b10_bar]) clause12 = Clause([lit_b10_bar, lit_b11_bar]) clause13 = Clause([lit_b10, lit_b12]) clause14 = Clause([lit_b11, lit_b12]) clause15 = Clause([lit_b13, lit_b14]) clause16 = Clause([lit_b14, lit_b15_bar]) clause17 = Clause([lit_b15, lit_b16]) clause_list = [ clause0, clause1, clause2, clause3, clause4, clause5, clause6, clause7, clause8, clause9, clause10, clause11, clause12, clause13, clause14, clause15, clause16, clause17 ] atom_list = [ b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16 ] return clause_list, atom_list
def write_false_belief_chapter(start_state, oracle, location, agent_ids, all_agents, questions=None): """ Creates list of clauses that constitute a true belief task. agent_ids: list that gives indices of agents in container. should be length 2. all_agents: list of all agents container: container to which the object is moved Warning: clauses will advance that state of the simulation, should clauses should be appended in order. """ a1, a2 = all_agents[agent_ids[0]], all_agents[agent_ids[1]] agent_ids = [aid + 1 for aid in agent_ids] # pick random object at location obj = np.random.choice(oracle.get_objects_at_location(location)) container_1 = oracle.get_object_container(obj) # pick random container in locations container_candidates = oracle.get_containers(location)[:] container_candidates.remove(container_1) container_2 = np.random.choice(container_candidates) chapter = [] # move agents into location if oracle.get_location(a1) == location: chapter.extend( [Clause([agent_ids[0]], LocationAction(oracle, (a1, location)))]) else: chapter.extend( [Clause([agent_ids[0]], EnterAction(oracle, (a1, location)))]) if oracle.get_location(a2) == location: chapter.extend( [Clause(agent_ids, LocationAction(oracle, (a2, location)))]) else: chapter.extend( [Clause(agent_ids, EnterAction(oracle, (a2, location), [a1]))]) chapter.extend([ Clause(agent_ids, ObjectLocAction(oracle, obj, [a1, a2])), Clause(agent_ids, ExitedAction(oracle, (a2))), Clause([agent_ids[0]], MoveAction(oracle, (a1, obj, container_2))), # Clause(agent_ids, EnterAction(oracle, (a2, location))), # closed container condition # TODO: fancy inheritance to copy start state # sample_question(start_state, oracle, a1, a2, obj, question) ]) # JUST ONE QUESTION SPLITS A STRING TODO TODO for question in questions: chapter.append( sample_question(start_state, oracle, a1, a2, obj, question)) return chapter
def generate_story_qs_at_end(self, world, tasks_per_story, tasks, questions, num_agents=6, num_locations=3, statement_noise=0): """ Allows user to specify chapter and question for each task in story. :tasks: list with length of tasks per story. Each entry is a string in the set {'tb','fb','sofb'} :questions: list with length of tasks per story. Each entry is a string in the set {'memory', 'reality', 'belief', 'search'} :statement_noise: probability of encountering noise sentence like 'The dog ran through the kitchen.' """ # Fetch agents and objects and select a random subset idx_support_dummy = [0] actors = world.get_actors() locations = world.get_locations() objects = world.get_objects() containers = world.get_containers() random_actors = np.random.choice(actors, size=num_agents, replace=False) random_locations = np.random.choice(locations, size=num_locations, replace=False) random_objects = np.random.choice(objects, size=num_locations * 2, replace=False) random_containers = np.random.choice(containers, size=num_locations * 2, replace=False) # Create the oracle oracle = Oracle(random_actors, random_locations, random_objects, random_containers) # Populate locations in the oracle with containers for i in range(len(random_locations)): location = random_locations[i] containers = random_containers[2 * i:2 * i + 2] oracle.set_containers(location, list(containers)) # Populate containers with objects for i in range(len(random_objects)): oracle.set_object_container(random_objects[i], random_containers[i]) # Need start state for memory question start_state = oracle.locations.obj_containers.copy() # Create story by task chapters = { 'tb': write_true_belief_chapter, 'fb': write_false_belief_chapter, 'sofb': write_second_order_false_belief_chapter } story = [] for i in range(tasks_per_story - 1): chapter = chapters[tasks[i]] location = np.random.choice(random_locations) agent_ids = np.random.choice(range(len(random_actors)), size=2, replace=False) story.extend( chapter(start_state, oracle, location, agent_ids, random_actors, [])) chapter = chapters[tasks[-1]] location = np.random.choice(random_locations) agent_ids = np.random.choice(range(len(random_actors)), size=2, replace=False) story.extend( chapter(start_state, oracle, location, agent_ids, random_actors, questions)) # At the end, at noise sentences randomly if statement_noise: noisy_story = [] prev_i = 0 noise = [ i for i in range(len(story)) if np.random.rand() < statement_noise ] for i in noise: noisy_story.extend(story[prev_i:i] + [Clause([], NoiseAction())]) prev_i = i noisy_story.extend(story[prev_i:]) return noisy_story return story
def _analyze_conflict(self, confl_clause, stage): def find_conflicting_clause_pairs(): conf_literal = confl_clause.get_unit() clauses = self.sentence.get_clauses_with(conf_literal.var) pos_lit = [] neg_lit = [] for clause in clauses: if (clause.is_unit()): if (clause.get_unit() is conf_literal): pos_lit.append(clause) elif (clause.get_unit().conflictsWith(conf_literal)): neg_lit.append(clause) return [item for item in itertools.product(pos_lit, neg_lit)] def reached_1_UIP(intermediate_lit_list, stage): return len( list(filter(lambda x: x.stage == stage, intermediate_lit_list))) <= 1 def resolved_clause(i_lit_list, stage): while not reached_1_UIP(i_lit_list, stage): curr_sec_vars = list( filter(lambda x: x.stage == stage, i_lit_list)) resolve_var = max(curr_sec_vars, key=attrgetter('imply_q')) if (resolve_var.antecedent != None): i_lit_list = list( set(resolve_var.antecedent.variables()).union( set(i_lit_list))) i_lit_list.remove(resolve_var) #print('+++', list(map(str, i_lit_list))) else: break return i_lit_list confl_clause_pairs = find_conflicting_clause_pairs() conf_var = confl_clause.get_unit().var learnt_clauses = [] for (clauseA, clauseB) in confl_clause_pairs: var_list = list( set(clauseA.variables()).union(clauseB.variables())) var_list.remove(conf_var) if (len(var_list) == 0): return ([], -1) roots = var_list to_remove = [] for var in var_list: if var != var.implied_by_roots[0]: if (set(var.implied_by_roots).issubset(set(roots))): to_remove.append(var) for var in to_remove: roots.remove(var) #print(list(map(str, roots))) learnt_clause = resolved_clause(roots, stage) max_stage = max([var.stage for var in learnt_clause]) new_vars = list(map(lambda x: -x, map(int, learnt_clause))) backtrack_stage = [] learnt_clauses = [] if (len(learnt_clause) == 1): learnt_clauses.append( Clause(new_vars, self.model, len(self.sentence.all_clauses()))) backtrack_stage.append(max_stage - 1) else: learnt_clause.sort(key=lambda x: x.stage, reverse=True) backtrack_stage.append(learnt_clause[1].stage) learnt_clauses.append( Clause(new_vars, self.model, len(self.sentence.all_clauses()))) bc_stage = min(backtrack_stage) return learnt_clauses, bc_stage
def addClause(self, clauseText): self.clauses.append(Clause(clauseText, len(self.clauses) + 1))
def make_singleton_clause(l): return Clause(-1, [l])
def genCNF(self): n = self.size expression = CNF(n) # Cell clauses for i in range(n): terms = [] for j in range(1, n + 1): terms.append(Term(j + n * i)) expression.add(Clause(terms)) # Row clauses for i in range(n): for j in range(1, n): number = n * i + j for l in range(1, n - j + 1): expression.add(Clause([-Term(number), -Term(number + l)])) # Columns clauses for j in range(1, n + 1): for i in range(n): number = n * i + j for l in range(1, n - i): expression.add( Clause([-Term(number), -Term(number + l * n)])) # Clauses diagonals left to right (upper bound) for i in range(n - 1): for j in range(i, n - 1): number = n * i + j + 1 for l in range(1, n - j): expression.add( Clause([-Term(number), -Term(number + l * (n + 1))])) # Clauses diagonals left to right (lower bound) for i in range(n - 1): for j in range(i): number = n * i + j + 1 for l in range(1, n - i): expression.add( Clause([-Term(number), -Term(number + l * (n + 1))])) # Clauses diagonals right to left (upper bound) for i in range(n): for j in range(n - i): number = n * i + j + 1 for l in range(1, j + 1): expression.add( Clause([-Term(number), -Term(number + l * (n - 1))])) # Clauses diagonals right to left (lower bound) for i in range(n): for j in range(n - i, n): number = n * i + j + 1 if (number != n * n): for l in range(1, n - i): expression.add( Clause( [-Term(number), -Term(number + l * (n - 1))])) return expression