def solve(self, query_relation, max_length=-1): if query_relation not in self.relations: return None if self.prev_relation == query_relation: cfg = self.prev_cfg else: query = Function() query.add_atom(query_relation, "x", "y") deter = utils.get_dfa_from_functions(self.functions, query_relation) cfg = query.get_longest_query_grammar(self.relations, self.uids) cfg = cfg.intersection(deter) self.prev_relation = query_relation self.prev_cfg = cfg if not cfg.is_empty(): for word in cfg.get_words(max_length=max_length): return utils.get_translation(self.fst, word) raise ExplorationNotDeepEnough("The depth " + str(max_length) + " given was not high enough.") return None
function2.add_atom("13", "z", "t") function2.set_input_variable("x") functions = [function0, function1, function2] linear_paths = utils.get_all_linear_paths(functions) print(linear_paths) enfa = utils.get_enfa_from_functions(functions) new_enfa = utils.get_folded_automaton(enfa) deter = utils.get_dfa_from_functions(functions) relation = "13" res_us = utils.accept_query(new_enfa, relation) susie_res, paths = utils.do_susie(linear_paths, relation) query = Function() query.add_atom(relation, "x", "y") cfg = query.get_longest_query_grammar(["12","12-","14","14-", "13","13-"]) cfg = cfg.intersection(deter) print(not cfg.is_empty()) print(res_us) print(susie_res, paths)
class TestFunction(unittest.TestCase): def setUp(self) -> None: self.function = Function() def test_create_empty_function(self): self.assertEqual(self.function.get_number_variables(), 0) self.assertEqual(self.function.get_number_atoms(), 0) def test_add_atom(self): self.function.add_atom("r", "x", "x") self.assertEqual(self.function.get_number_variables(), 1) self.assertEqual(self.function.get_number_atoms(), 1) self.function.add_atom("r", "y", "y") self.assertEqual(self.function.get_number_variables(), 2) self.assertEqual(self.function.get_number_atoms(), 2) self.function.add_atom("r", "x", "y") self.assertEqual(self.function.get_number_variables(), 2) self.function.add_atom("r", "t", "u") self.assertEqual(self.function.get_number_variables(), 4) def test_get_linear_paths(self): self.assertEqual(self.function.get_linear_paths(), []) self.function.add_atom("r1", "x", "y") self.assertEqual(sorted(self.function.get_linear_paths()), sorted([["r1"]])) self.function.add_atom("r2", "y", "z") self.assertEqual(sorted(self.function.get_linear_paths()), sorted([["r1"], ["r1", "r2"]])) self.function.add_atom("r3", "x", "z") self.assertEqual(sorted(self.function.get_linear_paths()), sorted([["r1"], ["r1", "r2"], ["r3"], ["r3", "r2-"]])) self.function.add_atom("r4-", "z", "y") self.assertEqual( sorted(self.function.get_linear_paths()), sorted([["r1"], ["r1", "r2"], ["r3"], ["r3", "r2-"], ["r1", "r4"], ["r3", "r4-"]])) def test_real_linear(self): self.function.add_atom("r1", "x", "y") self.function.add_atom("r2", "y", "z") self.assertTrue(self.function.is_linear()) def test_false_linear(self): self.function.add_atom("r1", "x", "y") self.function.add_atom("r2", "y", "z") self.function.add_atom("r2", "x", "z") self.assertFalse(self.function.is_linear()) def test_false_linear2(self): self.function.add_atom("r1", "x", "y") self.function.add_atom("r2", "z", "t") self.assertFalse(self.function.is_linear()) def test_get_all_linear_subfunctions(self): self.function.add_atom("r1", "x", "y") self.function.add_atom("r2", "y", "z") self.function.add_atom("r3", "y", "t") self.assertEqual(len(self.function.get_linear_subfunctions()), 3) for function in self.function.get_linear_subfunctions(): self.assertTrue(function.is_linear()) def test_get_xml_relation(self): self.function.name = "A" self.function.add_atom("r1", "xxx", "yyy") self.function.add_atom("r2", "yyy", "zzz") self.function.add_atom("r2", "zzz", "ttt") self.function.set_existential_variable("zzz") xml = self.function.get_xml_relation() self.assertIn("View_A", xml) self.assertIn("xxx", xml) self.assertIn("yyy", xml) self.assertNotIn("zzz", xml) self.assertIn("ttt", xml) def test_get_xml_dependencies(self): self.function.name = "A" self.function.add_atom("r1", "xxx", "yyy") self.function.add_atom("r2", "yyy", "zzz") self.function.add_atom("r2", "zzz", "ttt") self.function.set_existential_variable("zzz") xml = self.function.get_xml_dependencies() self.assertEqual(xml.count("View_A"), 2) self.assertEqual(xml.count("xxx"), 4) self.assertEqual(xml.count("yyy"), 6) self.assertEqual(xml.count("ttt"), 4) self.assertEqual(xml.count("zzz"), 4) def test_existential(self): self.assertEqual(self.function.get_number_existential_variables(), 0) self.function.add_atom("r1", "x", "y") self.function.set_existential_variable("y") self.assertEqual(self.function.get_linear_paths(), []) self.function.add_atom("r2", "y", "z") self.assertEqual(sorted(self.function.get_linear_paths()), sorted([["r1", "r2"]])) def test_set_input_variable(self): self.function.add_atom("r1", "x", "y") self.function.set_input_variable("y") self.assertEqual(self.function.get_linear_paths(), [["r1-"]]) def test_get_longest_query(self): self.assertEqual(self.function.get_longest_query(), []) self.function.add_atom("r1", "x", "y") self.assertEqual(self.function.get_longest_query(), ["r1"]) def test_grammar(self): self.function.add_atom("r1", "x", "y") relations = ["r1", "r2", "r1-", "r2-"] uids = [UID("r1", "r2")] cfg = self.function.get_longest_query_grammar(relations, uids) self.assertTrue(cfg.contains(["r1"])) self.assertTrue(cfg.contains(["r2", "r2-", "r1"])) self.assertFalse(cfg.contains(["r2", "r1"])) def test_get_relations_and_inverses(self): self.assertEqual(self.function.get_relations_and_inverses(), set()) self.function.add_atom("r1", "x", "y") self.assertEqual(self.function.get_relations_and_inverses(), {"r1", "r1-"})
# enfa = utils.get_enfa_from_functions(functions) # enfa = utils.get_folded_automaton(enfa) fst = utils.get_transducer_parser(functions) answered = 0 sizes = [] for relation in relations: logging.info("Processing %s", relation) query = Function() query.add_atom(relation, "x", "y") deter = utils.get_dfa_from_functions(functions, relation) cfg = query.get_longest_query_grammar(relations, uids) cfg = cfg.intersection(deter) if not cfg.is_empty(): logging.info("%s can be answered.", relation) answered += 1 for word in cfg.get_words(): logging.info(str(word)) logging.info(str(utils.get_translation(fst, word))) sizes.append(len(word)) break else: logging.info("%s CANNOT be answered", relation) logging.info("%f queries were answered", answered / len(relations) * 100.0) logging.info("The mean size of the plan is %f",