def visit(self, clause): new_terms = [] for term in clause.terms: new_term = ~term if clause.negate else term new_terms += [self.visit(new_term)] return FreeClause(new_terms, False)
class Predicate: components: FreeClause = FreeClause([]) def __str__(self): return str(self.components) def propositionalize(self): remove_implications = ImplicationsVisitor() components = remove_implications.visit(self.components) canonicalize = CanonicalizeVisitor() components = canonicalize.visit(components) globalize = GlobalizeVisitor() components = globalize.visit(components) skolem_visitor = SkolemVisitor() components = skolem_visitor.visit(components) simplify_visitor = SimplifyVisitor() components = FreeClause([simplify_visitor.visit(components)]) distribute_visitor = DistributeVisitor() components = distribute_visitor.visit(components) clausify_visitor = ClausifyVisitor() components = clausify_visitor.visit(components).clauses return Predicate(components)
def solve(kb: HornKB, query): subst_gen = backward_chain_query(kb, query) for subst in subst_gen: return subst_all(FreeClause(list(query.terms)), subst) return None
def make_clause(head_parse, body_parse): if "constant" in head_parse: head = make_fact(head_parse["constant"]) else: head = make_relation(head_parse["relation"]) iter_body = iter(body_parse) first_parse = next(iter_body) body_clauses = make_body_term(first_parse) for term in iter_body: body_clauses = And(make_body_term(term), body_clauses) body = body_clauses vars_visitor = FreeVarVisitor() head_vars = vars_visitor.visit(head) body_vars = vars_visitor.visit(body) vars = set(head_vars + body_vars) clause = Implies(body, head) for var in vars: clause = Exists(var, clause) return FreeClause([clause])
def visit(self, clause: FreeClause): terms = clause.terms new_terms = [] for term in terms: new_terms += [self.visit(term)] return FreeClause(new_terms, clause.negate)
def prettify(clause: HornClause): new_body = HornClause._make_or(clause.body) free_clause = FreeClause([Or(clause.head, ~new_body)]) new_terms = [] canonicalize = CanonicalizeVisitor() for term in free_clause.terms: if type(term ) is Or: # from Horn's, must be one positive and one negative if term.operand1.negate: new_terms += Implies(canonicalize.visit(term.operand1), term.operand2) else: new_terms += [ Implies(canonicalize.visit(term.operand2), term.operand1) ] else: new_terms += [term] return FreeClause(new_terms)
def visit(self, clause): terms = clause.terms if self.body == clause: return self.subst if self.body in clause: new_terms = [] for term in terms: new_terms += [self.visit(term)] return FreeClause(new_terms, clause.negate) return clause