def test_depth_more_than_nodes(self) -> None: # In this case, the graph has no way to satisfy the min_depth requirement. # The user, or the higher level wrapper should make sure given proper # parameters. Otherwise, we will create the following output. solving_context = ClingoContext(number_of_nodes=3, min_depth=5) with self.assertRaises(expected_exception=RuntimeError, msg="Received unreasonable parameters."): agentGenerator.generate_logic_rules(solving_context)
def create_agent(agents: List[Agent], agent_numbers: List[int], profiles: List[Dict[str, Any]]): for index, agent_number in enumerate(agent_numbers): # The number of agents may greater than the number of profiles # So, we are round robin through each profile for the agent here. profile = profiles[index % len(profiles)] solving_context = ClingoContext( number_of_nodes=profile["number_of_nodes"], min_depth=profile["min_depth"], min_classes=profile["min_classes"], min_interfaces=profile["min_interfaces"], lower_bound=profile["lower_bound"], higher_bound=profile["higher_bound"], min_stub_classes=profile["min_stub_classes"], min_stub_interfaces=profile["min_stub_interfaces"], degree_distribution=profile["degree_distribution"], ) generator = HackCodeGenerator(solving_context) # To avoid two agents using same profile to produce the same output, # we are using model_count to enumerate the next solution with this profile. generator.model_count = index // len(profiles) combined_rules = agentGenerator.generate_logic_rules( solving_context, f"A{agent_number}") agents[agent_number] = Agent(generator, solving_context) agentGenerator.do_reasoning(combined_rules, generator)
def test_depth_less_than_nodes(self) -> None: solving_context = ClingoContext(number_of_nodes=12, min_depth=3) exp = [ 'internal_symbols("S0", 0;"S1", 1;"S2", 2;"S3", 3;"S4", 4;"S5", 5;"S6",' ' 6;"S7", 7;"S8", 8;"S9", 9;"S10", 10;"S11", 11).', 'extends_to("S0", "S4").', 'extends_to("S4", "S8").', ] self.assertListEqual( exp, agentGenerator.generate_logic_rules(solving_context))
def test_degree_distribution(self) -> None: solving_context = ClingoContext(number_of_nodes=12, degree_distribution=[1, 3, 5]) exp = [ 'internal_symbols("S0", 0;"S1", 1;"S2", 2;"S3", 3;"S4", 4;"S5", 5;"S6",' ' 6;"S7", 7;"S8", 8;"S9", 9;"S10", 10;"S11", 11).', ":- #count{X : in_degree(X, 0)} < 1.", ":- #count{X : in_degree(X, 1)} < 3.", ":- #count{X : in_degree(X, 2)} < 5.", ] self.assertListEqual( exp, agentGenerator.generate_logic_rules(solving_context))
def test_depth_equals_to_nodes(self) -> None: solving_context = ClingoContext(number_of_nodes=7, min_depth=7) exp = [ 'internal_symbols("S0", 0;"S1", 1;"S2", 2;"S3", 3;"S4", 4;"S5",' ' 5;"S6", 6).', 'extends_to("S0", "S1").', 'extends_to("S1", "S2").', 'extends_to("S2", "S3").', 'extends_to("S3", "S4").', 'extends_to("S4", "S5").', 'extends_to("S5", "S6").', ] self.assertListEqual( exp, agentGenerator.generate_logic_rules(solving_context))
def test_unsatisfiable_parameters(self) -> None: # Given 5 nodes, but asking for 3 classes + 4 interfaces with solving_context = ClingoContext(number_of_nodes=5, min_classes=3, min_interfaces=4) hack_codegen = hackGenerator.HackCodeGenerator(solving_context) with self.assertRaises(expected_exception=RuntimeError, msg="Unsatisfiable."): agentGenerator.do_reasoning( additional_programs=agentGenerator.generate_logic_rules( solving_context), generator=hack_codegen, )
def test_hack_code_gen_with_partial_dependency_graph_given_by_user( self) -> None: solving_context = ClingoContext( number_of_nodes=12, min_depth=3, min_classes=3, min_interfaces=4, lower_bound=1, higher_bound=5, ) deps = """\ Extends A -> Type B Extends I -> Type B Extends T -> Type A Type A -> Type B Type I -> Type B Type T -> Type A, Type B""" exp = """\ <?hh class S9 {} class S10 {} class S11 {} interface A extends T {} interface B extends A,I {} interface I {} interface T {} interface S0 {} interface S1 {} interface S2 {} interface S3 {} interface S4 extends S0 {} interface S5 {} interface S6 {} interface S7 {} interface S8 extends S4 {} """ hack_codegen = hackGenerator.HackCodeGenerator(solving_context) combined_rules = agentGenerator.generate_logic_rules( solving_context) + agentGenerator.extract_logic_rules( deps.split("\n")) agentGenerator.do_reasoning(additional_programs=combined_rules, generator=hack_codegen) self.assertEqual(str(hack_codegen), exp)
def test_hack_code_gen(self) -> None: solving_context = ClingoContext( number_of_nodes=12, min_depth=3, min_classes=3, min_interfaces=4, lower_bound=1, higher_bound=5, min_stub_classes=4, min_stub_interfaces=1, degree_distribution=[1, 3, 5], ) hack_codegen = hackGenerator.HackCodeGenerator(solving_context) agentGenerator.do_reasoning( additional_programs=agentGenerator.generate_logic_rules( solving_context), generator=hack_codegen, ) self.assertTrue(hack_codegen.validate())
def test_sum_of_degrees_greater_than_nodes(self) -> None: solving_context = ClingoContext(number_of_nodes=12, degree_distribution=[3, 5, 7]) with self.assertRaises(expected_exception=RuntimeError, msg="Received unreasonable parameters."): agentGenerator.generate_logic_rules(solving_context)