def test_axiom_to_pcnf(self): a = Predicate('A', ['x']) b = Predicate('B', ['y']) c = Predicate('C', ['z']) # Simple test of disjunction over conjunction axi_one = Axiom(Universal(['x', 'y', 'z'], a | b & c)) axi_one = axi_one.ff_pcnf() self.assertEqual('∀(z,y,x)[((A(z) | B(y)) & (A(z) | C(x)))]', repr(axi_one)) # Test recursive distribution #axi_one = Axiom(Universal(['x','y','z'], a | (b & (a | (c & b))))) #print(repr(axi_one)) #self.assertEqual('', repr(axi_one.to_pcnf())) # Simple sanity check, it's already FF-PCNF axi_two = Axiom(Universal(['x', 'y', 'z'], (a | b) & c)) axi_two = axi_two.ff_pcnf() self.assertEqual('∀(z,y,x)[(C(x) & (A(z) | B(y)))]', repr(axi_two)) # Sanity check we remove functions c = Predicate('C', ['z', Function('F', ['z'])]) axi_three = Axiom(Universal(['x', 'y', 'z'], a | b & c)) axi_three = axi_three.ff_pcnf() self.assertEqual( '∀(z,y,x,w)[((A(z) | C(x,w) | ~F(x,w)) & (A(z) | B(y)))]', repr(axi_three))
def test_axiom_function_replacement(self): f = Function('f', ['x']) t = Function('t', ['y']) a = Predicate('A', [f]) b = Predicate('B', [f, t]) axi = Axiom(Universal(['x'], a | a & a)) self.assertEqual(repr(axi), '∀(x)[(A(f(x)) | (A(f(x)) & A(f(x))))]') axi = Axiom(Universal(['x', 'y'], b))
def test_can_filter_axioms(self): a = Predicate('A', ['x']) b = Predicate('B', ['x']) simple_subclass = Axiom(Universal(['x'], ~a | b)) simple_disjoint = Axiom(Universal(['x'], ~a | ~b)) matching_patterns = Filter.filter_axiom(simple_subclass) self.assertTrue(Pattern.subclass_relation in matching_patterns) not_matching = Filter.filter_axiom(simple_disjoint) self.assertFalse(Pattern.subclass_relation in not_matching)
def test_axion_to_tptp(self): a = Predicate('A', ['x']) b = Predicate('B', ['y']) c = Predicate('C', ['z']) d = Predicate('D', ['u']) axiom_one = Axiom(Universal(['x', 'y', 'z', 'u'], ~a | ~d | b | c)) axiom_two = Axiom(Universal(['x', 'y', 'z', 'u'], ~a | ~d | b | c)) print() print(axiom_one.to_tptp()) print(axiom_two.to_tptp())
def test_axiom_variable_standardize(self): a = Predicate('A', ['x']) b = Predicate('B', ['y', 'x']) c = Predicate('C', ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) axi = Axiom(Universal(['x'], a | a & a)) self.assertEqual(repr(axi.standardize_variables()), '∀(z)[(A(z) | (A(z) & A(z)))]') axi = Axiom(Universal(['x', 'y'], b)) self.assertEqual(repr(axi.standardize_variables()), '∀(z,y)[B(y,z)]') axi = Axiom( Existential(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], c)) self.assertEqual(repr(axi.standardize_variables()), '∃(z,y,x,w,v,u,t,s,r)[C(z,y,x,w,v,u,t,s,r)]')
def test_axiom_simple_function_replacement(self): f = Function('f', ['x']) t = Function('t', ['y']) p = Function('p', ['z']) a = Predicate('A', [f, t, p]) b = Predicate('B', [f, t]) c = Predicate('C', [f]) axi = Axiom(Universal(['x', 'y', 'z'], a)) #self.assertEqual(repr(axi.substitute_functions()), '∀(x,y,z)[∀(f2,t3,p4)[(A(f2,t3,p4) | ~(f(x,f2) & t(y,t3) & p(z,p4)))]]') axi = Axiom(Universal([ 'x', ], ~c)) #self.assertEqual(repr(axi.substitute_functions()), '∀(x)[~~∀(f5)[(C(f5) | ~f(x,f5))]]') #c = Predicate('C', [Function('f', [Function('g', [Function('h', ['x'])])])]) axi = Axiom(Universal(['x'], c))
def add_conjecture(self, logical): """ Accepts a logical object and creates an accompanying Axiom object out of it :param Logical logical, a parsed logical object :return None """ self.conjecture.append(Axiom.Axiom(logical))
def add_axiom(self, logical): """ Accepts a logical object and creates an accompanying Axiom object out of it and stores it in this ontology :param Logical logical, a parsed logical object :return None """ self.axioms.append(Axiom(logical))
def test_owl_subclass(self): a = Predicate('A', ['x']) b = Predicate('B', ['x']) c = Predicate('C', ['x']) d = Predicate('D', ['x']) subclass_relation = Axiom(Universal(['x'], ~d | b | c)) onto = Ontology("Derp") onto.axioms.append(subclass_relation) print(onto.to_owl())
def test_can_match_subclass_pattern(self): # Simple sanity check a = Predicate('A', ['x']) b = Predicate('B', ['x']) simple = Axiom(Universal(['x'], ~a | b)) match = Pattern.subclass_relation(simple) self.assertIsNotNone(match) self.assertEqual(match[1].pop(), a) self.assertEqual(match[2].pop(), b) # Check against longer disjunctions a = Predicate('A', ['x']) b = Predicate('B', ['x']) c = Predicate('C', ['x']) d = Predicate('D', ['x']) ext = Axiom(Universal(['x'], ~a | ~b | c | d)) match = Pattern.subclass_relation(ext) self.assertIsNotNone(match) self.assertEqual(match[1], [a, b]) self.assertEqual(match[2], [c, d])
def to_owl(self, resolve=True): """ Return a string representation of this ontology in OWL format. If this ontology contains imports will translate those as well and concatenate all the axioms. :return String onto, this ontology in OWL format """ # Create new OWL ontology instance # need to use normalized path to work properly on Windows onto = Owl( self.name, self.name.replace(os.path.normpath(self.basepath[1]), self.basepath[0]).replace('.clif', '.owl').replace( os.sep, '/')) axioms = self.get_all_axioms(resolve) # keeping track of classes (unary predicates) and properties (binary predicates) encountered # to avoid redundant declarations # predicates with the same arity and name are assumed to be identical classes = set() properties = set() # Loop over each Axiom and filter applicable patterns for axiom, path in axioms: print('Axiom: {} from {}'.format(axiom, path)) pcnf = axiom.ff_pcnf() print('FF-PCNF: {}'.format(pcnf)) for unary in axiom.unary(): if unary.name not in classes: classes.add(unary.name) onto.declare_class(unary.name) for binary in axiom.binary(): if binary.name not in properties: properties.add(binary.name) onto.declare_property(binary.name) for pruned in Translation.translate_owl(pcnf): tmp_axiom = Axiom(pruned) pattern_set = Filter.filter_axiom(tmp_axiom) #Collector for extracted patterns for pattern in pattern_set: extraction = pattern(tmp_axiom) if extraction is not None: print(' - pattern', extraction[0]) Translation.produce_construct(extraction, onto) for extra in pcnf.extra_sentences: for extra_pruned in Translation.translate_owl(extra): tmp_axiom = Axiom(extra_pruned) pattern_set = Filter.filter_axiom(tmp_axiom) #Collector for extracted patterns for pattern in pattern_set: extraction = pattern(tmp_axiom) if extraction is not None: print(' - (extra) pattern', extraction[0]) Translation.produce_construct(extraction, onto) print() # TODO: Find another way to do this instead of case by case # etree.ElementTree html encodes special characters. Protege does not like this. # return onto.tostring() return onto