def p_literal(p): '''literal : LPAREN NOT_KEY predicate RPAREN | predicate''' if len(p) == 2: p[0] = Literal.positive(p[1]) elif len(p) == 5: p[0] = Literal.negative(p[3])
def main(): numQueries = 0 queries = [] numTruths = 0 truths = [] with open("./input.txt") as inp: line = inp.readline() # First line is always the number of queries numQueries = int(line) # n queries for i in range(numQueries): line = inp.readline() queries.append(line.strip()) line = inp.readline() # This is followed by the number of truths numTruths = int(line) for i in range(numTruths): line = inp.readline() truths.append(line.strip()) kb = KnowledgeBase(truths) results = [] for q in queries: lit = Literal(q, len(truths) + 1) lit.negate() result = kb.proveByResolution2([lit], 0) print("{}: {}".format(q, result)) results.append(str(result).upper()) with open('./output.txt', 'w') as op: op.write('\n'.join([r for r in results]))
def compositeToBasicRules(self, pred, body, varOrder = None): variables = set() rules = [] rule = Rule() passOperator = '' for literal in body: newLiteral = None if isinstance(literal, string_types): for literalString in literal.split('^'): if re.match('[!#]?[a-z]+[_0-9\([a-zA-Z,]+\)]?' , literalString): newLiteral = Literal.fromString(literalString) rule.body.append(newLiteral) variables = variables.union(newLiteral.vars()) elif re.match('[!#]', literalString): passOperator = literalString else: freshPred = freshPredicate() (newLiteralVars, newLiteralRules) = Rule.compositeToBasicRules(freshPred, literal) rules += newLiteralRules newLiteral = Literal.fromString( passOperator + freshPred + '(' + ','.join(newLiteralVars) + ')') rule.body.append(newLiteral) variables = variables.union(newLiteral.vars()) passOperator = '' if varOrder is not None: rule.head = Atom.fromString(pred + '(' + varOrder + ')') else: rule.head = Atom.fromString(pred + '(' + ','.join(map(str, variables)) + ')') rules.append(rule) return (variables, rules)
def __init__(self, atoms): self._atoms = atoms self._terms = [] self._weights = {} self.__index = {} for atom in self._atoms: self.__index[Literal.positive(atom)] = set() self.__index[Literal.negative(atom)] = set()
def p_literal(p): '''literal : NEGATION LPAREN atom RPAREN | NEGATION atom | atom''' if len(p) == 5: p[0] = Literal.negative(p[3]) elif len(p) == 3: p[0] = Literal.negative(p[2]) else: p[0] = Literal.positive(p[1])
def add_to_domain(domain): ############################################ # Let's now create TYPES AND PREDICATES ############################################ domain.add_type('boxes') domain.add_pred('open', [('?x', 'boxes'), ('?z', 'block')]) domain.del_pred('handempty', 0) # print(repr(domain.operators[3])) ############################################ # Let's now create an OPERATOR ############################################ # print(domain.operators[3].precond) params = [Term.variable('?x', type='blocks'), Term.variable('?y', type='blocks')] precond=[] precond.append(Literal(Predicate('=', [Term.variable('?x'), Term.variable('?y')]), False)) precond.append(Literal(Predicate('on', [Term.variable('?x'), Term.variable('?y')]), True)) precond.append(Literal(Predicate('clear', [Term.variable('?x')]), True)) precond.append(Literal(Predicate('handempty', []), True)) # print(domain.operators[3].effects) effect=[] effect.append((1.0, Literal(Predicate('holding', [Term.variable('?x')]), True))) effect.append((1.0, Literal(Predicate('clear', [Term.variable('?y')]), True))) effect.append((1.0, Literal(Predicate('clear', [Term.variable('?x')]), False))) effect.append((1.0, Literal(Predicate('handempty', []), False))) effect.append((1.0, Literal(Predicate('on', [Term.variable('?x'), Term.variable('?y')]), False))) # print(repr(effect)) domain.add_action('pick-up-b', params, precond, effect)
def __update_index(self, term, index): term = set(term) for atom in self._atoms: positive_literal = Literal.positive(atom) negative_literal = Literal.negative(atom) if positive_literal in term: self.__index[positive_literal].add(index) continue if negative_literal in term: self.__index[negative_literal].add(index) continue self.__index[positive_literal].add(index) self.__index[negative_literal].add(index)
def get_elements_from_string(self, text): formula_strings = text.split(" ") elements = [] for formula_string in formula_strings: if formula_string == '' or formula_string == text: continue if utils.is_digit(formula_string): if (int(formula_string) == 0): break literal = Literal(formula_string) elements.append(literal) else: inner_elements = self.get_elements_from_string(formula_string) # if we have more than one inner element, wrap them in another formula if len(inner_elements) > 0: new_formula = Formula(Operation.OR) new_formula.add_elements(inner_elements) elements.append(new_formula) else: elements.extend(inner_elements) return elements
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(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 __init__(self, lit_list, model, _id): self.literals = [Literal(model.get_var_obj(abs(lit_num)), lit_num > 0) for lit_num in lit_list] self._length = len(lit_list) self.id = _id if( self._length >= 2): self._watched_lit = self.literals[:2] else: self._watched_lit = [self.literals[0]]
def parse_clause(clause_str): list_literal_str = clause_str.strip().split('OR') clause = Clause() for literal_str in list_literal_str: literal = Literal.parse_literal(literal_str) clause.add(literal) clause.flatten() return clause
def test_combine(self): parser = Parser() transition_model = ''' 1.000::running(c1, 1) :- running(c1, 0). ''' atoms1, rules1 = parser.parse(transition_model) wdnf1 = WeightedDNF(set(atoms1.keys())) for index, rule in enumerate(rules1): pos_term = tuple( sorted([Literal.positive(rule.head)] + list(rule.body))) wdnf1.add_term(pos_term, rule.probability) neg_term = tuple( sorted([Literal.negative(rule.head)] + list(rule.body))) wdnf1.add_term(neg_term, 1 - rule.probability) value_model = ''' V(0) :- not(running(c1, 1)), not(running(c2, 1)), not(running(c3, 1)). V(1) :- running(c1, 1), not(running(c2, 1)), not(running(c3, 1)). V(1) :- not(running(c1, 1)), running(c2, 1), not(running(c3, 1)). V(1) :- not(running(c1, 1)), not(running(c2, 1)), running(c3, 1). V(2) :- running(c1, 1), running(c2, 1), not(running(c3, 1)). V(2) :- running(c1, 1), not(running(c2, 1)), running(c3, 1). V(2) :- not(running(c1, 1)), running(c2, 1), running(c3, 1). V(3) :- running(c1, 1), running(c2, 1), running(c3, 1). ''' atoms2, rules2 = parser.parse(value_model) wdnf2 = WeightedDNF(set(atoms2.keys())) for index, rule in enumerate(rules2): wdnf2.add_term(sorted(rule.body), float(rule.head[2:-1])) prod = combine(wdnf1, wdnf2, float.__mul__) self.assertEqual(len(prod), len(wdnf2)) pos = Literal.positive('running(c1,1)') neg = Literal.negative('running(c1,1)') r1 = Literal.positive('running(c1,0)') for weight, term in prod: self.assertEqual(len(term), 4) if neg in term: self.assertEqual(weight, 0.0) if pos in term: count = sum([ literal.is_positive() for literal in term if literal != r1 ]) self.assertEqual(weight, float(count))
def fromString(self, string): newRule = Rule() string = string.replace(' ','') tmp = string.split(':-') newRule.head = Atom.fromString(tmp[0]) if len(tmp) > 1: for literalString in tmp[1].split('^'): newRule.body.append(Literal.fromString(literalString)) return newRule
def getProofByResolution(self, l: Literal): l.negate() # Negate the literal! inputLiterals = [l] literalCopy = deepcopy(self.literalMap) sentenceCopy = deepcopy(self.sentences) alreadySelected = {} while True: # Iterate though all input literals to get the best matching sentence in KB sentenceCountMap = {} bestSentence = -1 for inlit in inputLiterals: key = (inlit.identifier, inlit.litType) locations = literalCopy.get(key, []) for loc in locations: sentence = sentenceCopy[loc] literals = sentence.literals for lit in literals: if (lit.identifier, lit.litType) == key and ( lit.canBeResolvedBy(inlit) or inlit.canBeResolvedBy(lit) ) and lit.negated != inlit.negated: # These can be resolved sentenceCountMap[loc] = sentenceCountMap.get( loc, 0) + 1 if sentenceCountMap[loc] > sentenceCountMap.get( bestSentence, -1): bestSentence = loc break # There is no sentence with at least one of the appropriate literals if bestSentence == -1: return False neededSentence = sentenceCopy[bestSentence] inputLiterals = getResolution(neededSentence, inputLiterals) if len(inputLiterals) == 0: self.sentences.append(Sentence(str(l))) self.literalMap[(l.identifier, l.litType)] = self.literalMap.get( (l.identifier, l.litType), []) + [len(self.sentences) - 1] return True
def substitute(lit: Literal, unification: dict): # print("Trying to unify {} with {}".format(str(lit), unification)) # For debug purposes if lit.litType != 'P': # If the unification does not contain this identifier, then just return this lit = unification.get(lit, lit) return lit for i in range(len(lit.args)): lit.args[i] = substitute(lit.args[i], unification) return lit
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 setUp(cls): cls.r1 = 'running(c1,1)' cls.r2 = 'running(c2,1)' cls.r3 = 'running(c3,1)' cls.lp1 = Literal.positive(cls.r1) cls.ln1 = Literal.negative(cls.r1) cls.lp2 = Literal.positive(cls.r2) cls.ln2 = Literal.negative(cls.r2) cls.lp3 = Literal.positive(cls.r3) cls.ln3 = Literal.negative(cls.r3)
def __init__(self, inp : str, sNum : int): # Replace implication with # sent = inp.replace("=>", "#").strip() isImplication = sent.rfind("#") != -1 sent = sent.split(" ") # Alternate to get literals self.literals = [Literal(l, sNum) for l in sent[::2]] # Alternate with one offset to get connectors self.connectors = [l for l in sent[1::2]] # If implication, convert to disjunction if isImplication: self.connectors[-1] = "|" for i in range(len(self.connectors) - 1): self.connectors[i] = "&" if self.connectors[i] == "|" else "|" for i in range(len(self.literals) - 1): self.literals[i].negate()
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 __lt__(self, value): sql = '%s < %%s' % self return Literal(sql, self, value)
def test_add_term(self): # value function wdnf1 = wdnf.WeightedDNF(self.atoms1) self.assertEqual(len(wdnf1), 0) for index, rule in enumerate(self.rules1): wdnf1.add_term(rule.body, int(rule.head[2:-1])) self.assertEqual(len(wdnf1), index + 1) fluents = ['running(c1,1)', 'running(c2,1)', 'running(c3,1)'] for fluent in fluents: pos = Literal.positive(fluent) neg = Literal.negative(fluent) t1 = set(wdnf1.terms_by_literals([pos])) t2 = set(wdnf1.terms_by_literals([neg])) self.assertEqual(len(t1), len(wdnf1) / 2) self.assertEqual(len(t2), len(wdnf1) / 2) self.assertEqual(t1 & t2, set()) self.assertEqual(t1 | t2, set(wdnf1.terms)) values = [0, 1, 2, 3] terms_sets = [set(wdnf1.terms_by_weight(v)) for v in values] self.assertEqual(sum([len(s) for s in terms_sets]), len(wdnf1)) for i in range(len(terms_sets[-1])): for j in range(i + 1, len(terms_sets)): self.assertEqual(terms_sets[i] & terms_sets[j], set()) # transition function wdnf2 = wdnf.WeightedDNF(self.atoms2) self.assertEqual(len(wdnf2), 0) for index, rule in enumerate(self.rules2): pos_term = tuple([Literal.positive(rule.head)] + list(rule.body)) wdnf2.add_term(pos_term, rule.probability) neg_term = tuple([Literal.negative(rule.head)] + list(rule.body)) wdnf2.add_term(neg_term, 1 - rule.probability) self.assertEqual(len(wdnf2), 2 * len(self.rules2)) next_state_fluents = [ 'running(c1,1)', 'running(c2,1)', 'running(c3,1)' ] for fluent in next_state_fluents: pos = Literal.positive(fluent) neg = Literal.negative(fluent) t1 = set(wdnf2.terms_by_literals([pos])) t2 = set(wdnf2.terms_by_literals([neg])) self.assertEqual(len(t1), len(t2)) inter = set(term for _, term in t1 & t2) self.assertTrue(pos not in inter) self.assertTrue(neg not in inter) actions = ['reboot(c1)', 'reboot(c2)', 'reboot(c3)'] for action in actions: pos = Literal.positive(action) neg = Literal.negative(action) t1 = set(wdnf2.terms_by_literals([pos])) t2 = set(wdnf2.terms_by_literals([neg])) inter = set(term for _, term in t1 & t2) self.assertTrue(pos not in inter) self.assertTrue(neg not in inter) if action == actions[0]: self.assertEqual(len(t1), len(wdnf2) - 6) self.assertEqual(len(t2), len(wdnf2) - 2) if action == actions[2]: self.assertEqual(len(t1), len(wdnf2) - 6) self.assertEqual(len(t2), len(wdnf2) - 2)
def p_ATOMIC_SENTENCE(t): '''ATOMIC_SENTENCE : STRING LPAREN STRING RPAREN''' t[0] = Literal(t[1], t[3], "ATOMIC_SENTENCE")
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 __eq__(self, value): sql = '%s = %%s' % self return Literal(sql, self, value)
def __ne__(self, value): sql = '%s <> %%s' % self return Literal(sql, self, value)
def __gt__(self, value): sql = '%s > %%s' % self return Literal(sql, self, value)
def add_game(self, game): for game_position in game: literal = Literal(game_position) self.add_element(literal)
def in_(self, value): if type(value) == list or type(value) == tuple: sql = '%s IN (%s)' % (self, ', '.join(['%s' for item in value])) else: sql = '%s IN (%%s)' % self return Literal(sql, self, value)
def like(self, value): sql = '%s LIKE %%s' % self return Literal(sql, self, str(value))