def test_unify(p, q, expected): p = parse(p, _allow_partial_expression=True) q = parse(q, _allow_partial_expression=True) expected = parse_substitution(expected) print('p=', p) print('q=', q) print('expected mgu(p,q)=', expected) try: subst = unification.unify(p, q) except unification.NotUnifiable: subst = None print('mgu(p,q)=', subst) if subst is None: assert p != q # not unifiable elif subst == {}: assert p == q # already unified else: # Applying unifier to both expressions should yield the same result. p1 = p.apply(subst) q1 = q.apply(subst) print('mgu(p,q)(p)=', p1) print('mgu(p,q)(q)=', q1) assert p1 == q1 assert subst == expected
def test_standardize_quantified_variables(f, expected, expected_subst): f = parse(f) expected = parse(expected, True) expected_subst = parse_substitution(expected_subst, True) rv = _walk(f, cnf._standardize_quantified_variables, expected_subst) assert rv == expected
def test_occurs_in(p, q, expected): p = parse(p, _allow_partial_expression=True) q = parse(q, _allow_partial_expression=True) try: assert p.occurs_in(q) == expected except TypeError: assert expected is None
def test_skolemize(f, expected, expected_subst): f = parse(f) expected = parse(expected, True) expected_subst = parse_substitution(expected_subst, True) rv = _walk(f, cnf._skolemize, expected_subst) assert rv == expected
def test_serialization(p): f = parse(p, _allow_partial_expression=True) # Methods 'loads' and 'dumps' are inversed. assert f == syntax.Node.loads(f.dumps()) # Methods 'parse' and '__str__' are inversed. assert f == parse(str(f), _allow_partial_expression=True)
def test_distribute_conjunction(f, expected): f = parse(f) expected = parse(expected, True) rv = _walk(f, cnf._distribute_conjunction) assert rv == expected f_tt, rv_tt = (utils.truth_table(k) for k in (f, rv)) assert f_tt == rv_tt
def test_eliminate_biconditional(f, expected): f = parse(f) expected = parse(expected, True) rv = _walk(f, cnf._eliminate_biconditional) assert rv == expected f_tt, rv_tt = (utils.truth_table(k) for k in (f, rv)) assert f_tt == rv_tt
def test_propagate_negation(f, expected): f = parse(f) expected = parse(expected, True) rv = _walk(f, cnf._propagate_negation) assert rv == expected f_tt, rv_tt = (utils.truth_table(k) for k in (f, rv)) assert f_tt == rv_tt
def test_standardize_free_variables(f, expected, expected_subst): f = parse(f) expected = parse(expected, True) expected_subst = parse_substitution(expected_subst, True) rv = _walk(f, cnf._standardize_free_variables, expected_subst) assert rv == expected f_tt, rv_tt = (utils.truth_table(k) for k in (f, rv)) assert f_tt == rv_tt
def _infer(premises, conclusion): premises = [parse(k) for k in premises] conclusion = parse(conclusion) print('premises =', premises) print('conclusion =', conclusion) binding = inference.infer(premises, conclusion) entailed = binding is not None print('entailed =', entailed) print('binding =', binding) return entailed, binding
def test_compose(r, s, expected): expr = ' & '.join({*r.keys(), *r.values(), *s.keys(), *s.values()}) r = parse_substitution(r) s = parse_substitution(s) expected = parse_substitution(expected) print('r=', r) print('s=', s) print('expected r*s=', expected) print('expr=', expr) subst = unification.compose(r, s) print('r*s=', subst) # Applying the composed substitution should yield the same result # as applying substitutions piecewise. if expr: expr = expr1 = parse(expr, _allow_partial_expression=True) for k in (r, s): expr1 = expr1.apply(k) print('r*s(expr)=', expr1) assert expr.apply(subst) == expr1 else: assert not r and not s assert subst == expected
def _truth_table(premises, conclusion, **kwargs): premises = [parse(k) for k in premises] conclusion = parse(conclusion) print('premises =', premises) print('conclusion =', conclusion) table = utils.truth_table(*premises, conclusion, header=True, **kwargs) entailed = True for row in table[1:]: premises_rvs = row[-len(premises) - 1:-1] conclusion_rv = row[-1] if premises_rvs and all(premises_rvs) and not conclusion_rv: entailed = False row.append("<---") print(utils.justify_table(table)) print('entailed =', entailed) return entailed
def add_axiom(kb: KnowledgeBase, arg: str) -> None: if not arg: print("Error: Expected 1 argument\n") return try: f = grammar.parse(arg) except grammar.InvalidSyntaxError: print("Error: Invalid syntax\n") return kb.add_axiom(f)
def test_parse(f, expected): if expected is not None: expected = syntax.Node.loads(expected) try: f = parse(f, _allow_partial_expression=True) except InvalidSyntaxError as e: if expected is not None: raise e else: f = None assert f == expected
def prove(kb: KnowledgeBase, arg: str) -> None: if not arg: print("Error: Expected 1 argument\n") return try: f = grammar.parse(arg) except grammar.InvalidSyntaxError: print("Error: Invalid syntax\n") return rv = kb.prove(f) if rv: print(f"Formula is entailed by the knowledge base.\n") else: print(f"Formula is not entailed by the knowledge base.\n")
def add_lemma(kb: KnowledgeBase, arg: str) -> None: if not arg: print("Error: Expected 1 argument\n") return try: f = grammar.parse(arg) except grammar.InvalidSyntaxError: print("Error: Invalid syntax\n") return rv = kb.add_lemma(f) if rv: print(f"Lemma was proven and was added to the " f"knowledge base.\n") else: print(f"Lemma was not proven and was not added to the " f"knowledge base.\n")
def query(kb: KnowledgeBase, arg: str) -> None: if not arg: print("Error: Expected 1 argument\n") return try: f = grammar.parse(arg) except grammar.InvalidSyntaxError: print("Error: Invalid syntax\n") return rv = kb.query(f) if rv is None: print(f"Error: Query is not entailed by the knowledge base.\n") return for k, v in rv.items(): print(f"{k} = {v}") print()
def test_apply_substitution(p, q, expected): p = parse(p, _allow_partial_expression=True) q = parse_substitution(q) expected = parse(expected) assert p.apply(q) == expected
def test_equivalent_expressions(p, q, expected): p = parse(p, _allow_partial_expression=True) q = parse(q, _allow_partial_expression=True) assert (p == q) == expected
def test_convert_to_cnf(f): f = parse(f) rv, replaced = cnf.convert_to_cnf(f) print('rv =', rv) assert rv.is_cnf()
def test_truth_table(expr, kwargs, expected): expr = parse(expr, _allow_partial_expression=True) rv = utils.truth_table(expr, **kwargs) print(utils.justify_table(rv)) assert rv == expected