def tree_to_term(tree, f, phi): if len(tree.children) == 2: return FuncTerm(f, [tree_to_term(c, f, phi) for c in tree.children]) elif len(tree.children) == 1: return FuncTerm(f, [tree_to_term(tree.children[0], f, phi), Const(phi)]) else: return Const(tree.label)
def list_to_term(ls, f): if len(ls) == 0: return Const('*') elif len(ls) == 1: return FuncTerm(f, [Const(str(ls[0])), Const('*')]) else: return FuncTerm(f, [Const(str(ls[0])), list_to_term(ls[1:], f)])
def get_backgrounds(self): for s in self.symbols: atom = Atom( self.preds[0], [Const(s), list_to_term([s], self.funcs[0]), Const('*')]) self.backgrounds.append(atom)
def get_language(self): self.preds = [Predicate('plus', 3)] self.funcs = [FuncSymbol('s', 1)] self.consts = [Const(x) for x in self.symbols] self.lang = Language(preds=self.preds, funcs=self.funcs, consts=self.consts, subs_consts=[Const('0')])
def get_language(self): self.preds = [Predicate('append', 3)] self.funcs = [FuncSymbol('f', 2)] self.consts = [Const(x) for x in self.symbols] self.lang = Language(preds=self.preds, funcs=self.funcs, consts=self.consts, subs_consts=[Const('*')])
def enumerate_facts(self, Q, C, infer_step): """ enumerate a set of necessary and sufficient ground atoms Inputs ------ Q : (Set[.logic.Atom], Set[.logic.Atom], Set[.logic.Atom], Set[.logic.Atom]) inductive logic programming problem (P, N, B, L) C : List[.logic.Clause] set of clauses from the clause-generation step infer_step : int number of steps of forward-chaining inference Returns ------- G : List[.logic.Atom] set of enumerated ground atoms """ pos_examples = Q.pos neg_examples = Q.neg backgrounds = Q.bk G = set(pos_examples + neg_examples + backgrounds) G_next = G G_past = G head_unifier_dic = {} for i in range(infer_step): S = set() for clause in C: for fi, fact in enumerate(G_next): if (clause.head, fact) in head_unifier_dic: unify_flag, theta_list = unify([fact, clause.head]) else: unify_flag, theta_list = unify([fact, clause.head]) head_unifier_dic[(clause.head, fact) ] = unify_flag, theta_list if unify_flag: clause_ = subs_list(clause, theta_list) B_i_list = clause_.body S = S.union(set(B_i_list)) G = G.union(S) G_past = G_past.union(G_next) G_next = S.difference(G_past) # SPECIAL p_ = Predicate('.', 1) false = Atom(p_, [Const('__F__')]) true = Atom(p_, [Const('__T__')]) G_given = set([false, true] + pos_examples + neg_examples + backgrounds) G_inter = G.intersection(G_given) G_add = G.difference(G_inter) return [false, true] + backgrounds + pos_examples + neg_examples + list(G_add)
def __init__(self, n=30, noise_rate=0.0): self.name = "member" self.pos_examples = [] self.neg_examples = [] self.backgrounds = [] self.init_clauses = [] p_ = Predicate('.', 1) false = Atom(p_, [Const('__F__')]) true = Atom(p_, [Const('__T__')]) self.facts = [false, true] self.lang = None self.noise_rate = noise_rate self.n = n self.max_len = 4 self.symbols = list('abc')
def list_to_examples(ls, pred, f): atoms = [] for x in ls: list_term = list_to_term(ls, f) atom = Atom(pred, [Const(x), list_term]) atoms.append(atom) return atoms
def get_language(self): self.preds = [Predicate('member', 2)] self.funcs = [FuncSymbol('f', 2)] self.consts = [Const(x) for x in self.symbols] self.lang = Language(preds=self.preds, funcs=self.funcs, consts=self.consts)
def _get_witnesses(self, concept_name): # TODO: maybe this function should be in ConceptDomain? or Concept? """ Return a list of constant that are witnesses for the given unary constant, or [] if none are found A witness is a constant c s.t. concept(x) implies x=c. Note that this does not necessarily mean that concept(c) holds. """ concept = self.domain.concepts[concept_name] assert concept.arity == 1 sort = concept.variables[0].sort assert sort != TopSort() constants = used_constants(concept.formula) x = Const(self._fresh_const_name(constants), sort) f = concept(x) def is_witness(c): try: return z3_implies(f, Eq(x, c)) except SortError: return False return [c for c in constants if is_witness(c)]
def get_neg_examples(self): i = 0 while i < self.n: n1 = random.randint(0, int(self.max_len)) n2 = random.randint(0, int(self.max_len)) n3 = random.randint(int(self.max_len / 2), self.max_len) ls1 = random_choices(self.symbols, k=n1) ls2 = random_choices(self.symbols, k=n2) ls3 = random_choices(self.symbols, k=n3) term1 = list_to_term(ls1, self.funcs[0]) term2 = list_to_term(ls2, self.funcs[0]) term3 = list_to_term(ls3, self.funcs[0]) a1 = random.choice(self.symbols) n2 = random.randint(1, int(self.max_len)) n3 = random.randint(1, int(self.max_len)) ls2 = random_choices(self.symbols, k=n2) ls3 = random_choices(self.symbols, k=n3) if a1 in ls2 and delete(a1, ls2) != ls3: term1 = Const(a1) term2 = list_to_term(ls2, self.funcs[0]) term3 = list_to_term(ls3, self.funcs[0]) atom = Atom(self.preds[0], [term1, term2, term3]) if not atom in self.neg_examples: self.neg_examples.append(atom) i += 1
def int_to_term(n): s = FuncSymbol('s', 1) zero = Const('0') num = zero for i in range(n): num = FuncTerm(s, [num]) return num
def get_pos_examples(self): i = 0 while len(self.pos_examples) < self.n: n = random.randint(2, self.max_len) x = random.choice(self.symbols) ls = random_choices(self.symbols, k=n) if x in ls: term1 = Const(x) term2 = list_to_term(ls, self.funcs[0]) atom = Atom(self.preds[0], [term1, term2]) self.pos_examples.append(atom)
def get_neg_examples(self): i = 0 while i < self.n: n = random.randint(1, self.max_len) # 長さnで満たすもの出すまで繰り返し flag = True while flag: x = random.choice(self.symbols) ls = random_choices(self.symbols, n) if not x in ls: atom = Atom( self.preds[0], [Const(x), list_to_term(ls, self.funcs[0])]) self.neg_examples.append(atom) i += 1 flag = False
def get_pos_examples(self): i = 0 while len(self.pos_examples) < self.n: a1 = random.choice(self.symbols) n2 = random.randint(1, int(self.max_len)) ls2 = random_choices(self.symbols, k=n2) if a1 in ls2: term1 = Const(a1) term2 = list_to_term(ls2, self.funcs[0]) term3 = list_to_term(delete(a1, ls2), self.funcs[0]) atom = Atom(self.preds[0], [term1, term2, term3]) if not atom in self.pos_examples: self.pos_examples.append(atom) i += 1
def _materialize_node(self, concept_name): """ Materialize a node, returns the witness constant """ concept = self.domain.concepts[concept_name] assert concept.arity == 1 sort = concept.variables[0].sort assert sort != TopSort() witnesses = self._get_witnesses(concept_name) if len(witnesses) > 0: c = witnesses[0] else: c = Const(self._fresh_const_name(), sort) # TODO: maybe we shouldn't split here, and create the concepts explicitly X = Var('X', c.sort) name = '={}'.format(c.name) self.domain.concepts[name] = Concept(name, [X], Eq(X, c)) self.domain.split(concept_name, name) self.suppose(concept(c)) return c
def get_backgrounds(self): # for s in self.symbols: # atom = Atom(self.preds[0], [Const(s), Const(s)]) # self.backgrounds.append(atom) for s in self.symbols: self.backgrounds.append(Atom(self.preds[0], [Const(s), Const(s)]))
def test(st): print st, "=", eval(st) S = UninterpretedSort('S') UnaryRelation = FunctionSort(S, Boolean) BinaryRelation = FunctionSort(S, S, Boolean) X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z']) U = Var('U', UnaryRelation) U1 = Var('U1', UnaryRelation) U2 = Var('U2', UnaryRelation) B = Var('B', BinaryRelation) B1 = Var('B1', BinaryRelation) B2 = Var('B2', BinaryRelation) nstar = Const('nstar', BinaryRelation) x = Const('x', S) y = Const('y', S) c11 = Concept('xy', [X], And(Eq(x, X), Eq(y, X))) c10 = Concept('x', [X], And(Eq(x, X), Not(Eq(y, X)))) c01 = Concept('y', [X], And(Not(Eq(x, X)), Eq(y, X))) c00 = Concept('other', [X], And(Not(Eq(x, X)), Not(Eq(y, X)))) cnstar = Concept('nstar', [X, Y], nstar(X, Y)) cnplus = Concept('nplus', [X, Y], And(nstar(X, Y), Not(Eq(X, Y)))) notexists = ConceptCombiner([U], Not(Exists([X], U(X)))) exists = ConceptCombiner([U], Exists([X], U(X))) singleton = ConceptCombiner([U], ForAll([X, Y],
def get_backgrounds(self): # pass zero = Const('0') self.backgrounds.append(Atom(self.preds[0], [zero, zero, zero]))
def parse_consts(self, line): ''' Parse string to function symbols ''' return [Const(x) for x in line.split(',')]
if __name__ == '__main__': def test(st): print st, "=", eval(st) S = UninterpretedSort('S') T = TopSort() UnaryRelationS = FunctionSort(S, Boolean) BinaryRelationS = FunctionSort(S, S, Boolean) UnaryRelationT = FunctionSort(T, Boolean) BinaryRelationT = FunctionSort(T, T, Boolean) X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z']) r = Const('r', BinaryRelationS) n = Const('n', BinaryRelationS) p = Const('p', UnaryRelationS) q = Const('q', UnaryRelationS) u = Const('u', UnaryRelationS) c11 = Concept([X], And(p(X), q(X))) c10 = Concept([X], And(p(X), Not(q(X)))) c01 = Concept([X], And(Not(p(X)), q(X))) c00 = Concept([X], And(Not(p(X)), Not(q(X)))) cu = Concept([X], u(X)) crn = Concept([X, Y], Or(r(X,Y), n(X,Y))) combiners = get_standard_combiners() combinations = get_standard_combinations()
return [tt() for s, tt in pairs] if __name__ == '__main__': S = UninterpretedSort('S') T = TopSort() UnaryRelationS = FunctionSort(S, Boolean) BinaryRelationS = FunctionSort(S, S, Boolean) UnaryRelationT = FunctionSort(T, Boolean) BinaryRelationT = FunctionSort(T, T, Boolean) XS, YS = (Var(n, S) for n in ['X', 'Y']) XT, YT = (Var(n, T) for n in ['X', 'Y']) xs, ys = (Const(n, S) for n in ['x', 'y']) xt, yt = (Const(n, T) for n in ['x', 'y']) rs = Const('r', BinaryRelationS) ps = Const('p', UnaryRelationS) rt = Const('r', BinaryRelationT) pt = Const('p', UnaryRelationT) tt = Const('tt', T) TT = Var('TT', T) f1 = And(ps(XS), ps(xs)) cf1 = concretize_sorts(f1) print repr(f1) print repr(cf1) assert f1 == cf1 print
elif res == z3.unsat: _implies_cache[key] = True result.append(True) else: # no caching of unknown results print "z3 returned: {}".format(res) assert False result.append(None) return result if __name__ == '__main__': S = UninterpretedSort('S') X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z']) BinRel = FunctionSort(S, S, Boolean) leq = Const('leq', BinRel) transitive1 = ForAll((X, Y, Z), Implies(And(leq(X, Y), leq(Y, Z)), leq(X, Z))) transitive2 = ForAll((X, Y, Z), Or(Not(leq(X, Y)), Not(leq(Y, Z)), leq(X, Z))) transitive3 = Not( Exists((X, Y, Z), And(leq(X, Y), leq(Y, Z), Not(leq(X, Z))))) antisymmetric = ForAll((X, Y), Implies(And(leq(X, Y), leq(Y, X), true), Eq(Y, X))) print z3_implies(transitive1, transitive2) print z3_implies(transitive2, transitive3) print z3_implies(transitive3, transitive1) print z3_implies(transitive3, antisymmetric) print
def get_backgrounds(self): # pass atom = Atom(self.preds[0], [Const('*'), Const('*'), Const('*')]) self.backgrounds.append(atom)