def generate_example_type_1(problem, nl_propositions): """Generates a type 1 training example. Args: problem: a lib.InferenceProblem instance. nl_propositions: the natural language versions of all the propositions appearing in "problem". Returns: An instance of "Example", or None if any issue was found. """ problem = ip.generate_problem_canonical_renaming(problem) if not problem: return None premises = problem.premises inferences = problem.inferences propositions = problem.propositions [problem_inference, _] = random.choice(inferences) nl_inference = rules.render_language_clause(problem_inference, propositions, nl_propositions) nl_premises = [] for premise in premises: nl_premises.append( rules.capitalize( rules.render_language_clause(premise, propositions, nl_propositions))) inputs = "Translate the following inference to logic notation: " inputs += (". ".join(nl_premises)) + f". Therefore {nl_inference}." targets = ". ".join([rules.render_logic_clause(x) for x in premises]) targets = (f"{targets}. Therefore " + f"{rules.render_logic_clause(problem_inference)}.") return lib.Example(inputs, targets, "1", problem)
def generate_example_type_2b(problem, one_step_inferences, propositions, nl_propositions): """Generates a type 2b training example. Args: problem: an InferenceProblem instance. one_step_inferences: the list of one step inferences that can be reahced form the premises. propositions: the list of propositions in the problem. nl_propositions: the natural language versions of "propositions". Returns: An instance of "lib.Example", or None if any issue was found. """ premises = problem.premises example_type = "2b" nl_premises = [] for premise in premises: nl_premises.append( rules.capitalize( rules.render_language_clause(premise, propositions, nl_propositions))) name_rule = random.choice([True, False]) rule_name = None nl_inferences = [] for [rule_inference, rule] in one_step_inferences: rule_name = rule.rule_name inference_str = rules.capitalize( rules.render_language_clause(rule_inference, propositions, nl_propositions)) if name_rule: inference_str += f" can be inferred via the {rule_name} rule" nl_inferences.append(inference_str) inputs = ("What can be inferred from the following premises in a single " "inference step (ignoring inferences that add new predicates or " "constants)? ") if name_rule: inputs += "Name the inference rule being used: " inputs += (". ".join(nl_premises)) + "." targets = (". ".join(nl_inferences)) + "." if not nl_inferences: example_type = "2b-empty" targets = "Nothing can be inferred from these premises." elif problem.contains_contradiction: example_type = "2b-cont" targets = ( "Since the premises are contradictory, we can infer anything " "from them.") return lib.Example(inputs, targets, example_type, problem)
def generate_example_type_2a(problem, one_step_inferences): """Generates a type 2a training example. Args: problem: a lib.InferenceProblem instance. one_step_inferences: the list of one step inferences that can be reahced form the premises. Returns: An instance of "Example", or None if any issue was found. """ premises = problem.premises example_type = "2a" name_rule = random.choice([True, False]) inputs = ("What can be inferred from the following premises in a single " "inference step (ignoring inferences that add new predicates or " "constants)? ") if name_rule: inputs += "Name the inference rule being used: " inputs += (". ".join([rules.render_logic_clause(x) for x in premises])) + "." inferences_str = [] for [rule_inference, rule] in one_step_inferences: rule_name = rule.rule_name inference_str = rules.render_logic_clause(rule_inference) if name_rule: inference_str += f" can be inferred via the {rule_name} rule" inferences_str.append(inference_str) targets = (". ".join(inferences_str)) + "." if not inferences_str: example_type = "2a-empty" targets = "Nothing can be inferred from these premises." elif problem.contains_contradiction: example_type = "2a-cont" targets = ( "Since the premises are contradictory, we can infer anything " "from them.") return lib.Example(inputs, targets, example_type, problem)
def generate_example_type_3b(problem, nl_propositions, probability_of_adding_direct_inference=0.1, answer_at_the_end=True): """Generates a type 3b training example. Args: problem: an InferenceProblem instance. nl_propositions: the natural language versions of "propositions". probability_of_adding_direct_inference: the probability of having one of the premises as the target im. answer_at_the_end: whether to put the answer at the end of the targets, or at the beginning. Returns: An instance of "Example", or None if any issue was found. """ # Since "unrelated" is usually larger, we randomly reduce it to size 1: example_type = "3b" premises = problem.premises unrelated = list(problem.unrelated) while len(unrelated) > 1: unrelated.remove(random.choice(unrelated)) choices = ([(x, "inference") for x in problem.inferences] + [(x, "contradiction") for x in problem.contradictions] + [([x, []], "unrelated") for x in unrelated]) # With some probability we also allow direct inferences (which are directly # given in the premises): if random.random() < probability_of_adding_direct_inference: for premise in premises: choices.append(([premise, []], "inference")) if not choices: return None ([target_inference, chain], inference_type) = random.choice(choices) name_rule = random.choice([True, False]) nl_premises = [] for premise in premises: nl_premises.append( rules.capitalize( rules.render_language_clause(premise, problem.propositions, nl_propositions))) nl_target_inference = rules.capitalize( rules.render_language_clause(target_inference, problem.propositions, nl_propositions)) inputs = "Consider the following premises. " inputs += (". ".join(nl_premises)) + ". " inputs += "Can we infer the following from them? " if name_rule: inputs += "If we can, name the inference rule being used: " inputs += nl_target_inference + "." if inference_type == "inference": if not chain: example_type = "3b-premise" if answer_at_the_end: targets = "That is one of the premises. Therefore, the answer is yes." else: targets = "Yes, that is one of the premises." elif len(chain) == 1: if name_rule: rule_name = chain[0][2] if answer_at_the_end: targets = ( "We can infer this via the " f"{rule_name} rule. Therefore, the answer is yes.") else: targets = f"Yes, we can infer this via the {rule_name} rule." else: targets = "Yes." else: if problem.contains_contradiction: example_type = "3b-cont" if answer_at_the_end: targets = "" else: if problem.contains_contradiction: targets = ( "Yes, the premises are contradictory, so we can infer " "anything from them. For example via the following " "inference chain.") else: targets = "Yes, via the following inference chain." for i in range(len(chain)): # Each element in the chain is: ("premises, inferences, name") if i == len(chain) - 1: targets += " Finally, from the fact that" else: targets += " From the fact that" # Premises: for j in range(len(chain[i][0])): premise = chain[i][0][j] nl_premise = rules.render_language_clause( premise, problem.propositions, nl_propositions) if j != 0: if j == len(chain[i][0]) - 1: targets += ", and that" else: targets += ", that" targets += f" {nl_premise}" targets += " we can infer that" # Inferences: for j in range(len(chain[i][1])): chain_inference = chain[i][1][j] nl_inference = rules.render_language_clause( chain_inference, problem.propositions, nl_propositions) if j != 0: targets += "," targets += f" {nl_inference}" if name_rule: targets += f" via {chain[i][2]}" targets += "." if answer_at_the_end: if problem.contains_contradiction: targets += ( " Therefore, the answer is yes. Notice, however, that " "the premises were contradictory, so we can infer " "anything from them.") else: targets += " Therefore, the answer is yes." elif inference_type == "contradiction": if problem.contains_contradiction: example_type = "3b-cont" if answer_at_the_end: targets = ("The premises are contradictory and we can infer " "anything from them. Therefore, the answer is yes.") else: targets = ( "Yes, the premises are contradictory, so we can infer " "anything from them.") elif len(chain) <= 1: example_type = "3b-no-1" if answer_at_the_end: targets = "That contradicts the premises. Therefore the answer is no." else: targets = "No, that contradicts the premises." else: example_type = "3b-no" if answer_at_the_end: targets = "" else: targets = "No, we can see why via the following inference chain." for i in range(len(chain)): # Each element in the chain is: ("premises, inferences, name") if i == len(chain) - 1: targets += " Finally, from the fact that" else: targets += " From the fact that" # Premises: for j in range(len(chain[i][0])): premise = chain[i][0][j] nl_premise = rules.render_language_clause( premise, problem.propositions, nl_propositions) if j != 0: if j == len(chain[i][0]) - 1: targets += ", and that" else: targets += ", that" targets += f" {nl_premise}" targets += " we can infer that" # Inferences: for j in range(len(chain[i][1])): chain_inference = chain[i][1][j] nl_inference = rules.render_language_clause( chain_inference, problem.propositions, nl_propositions) if j != 0: targets += "," targets += f" {nl_inference}" if name_rule: targets += f" via {chain[i][2]}" targets += "." targets = targets[:-1] # Remove the last dot. targets += f", which contradicts that {nl_target_inference}." if answer_at_the_end: targets += " Therefore, the answer is no." else: example_type = "3b-unrelated" if answer_at_the_end: targets = "We cannot infer that from the premises." targets += " Therefore the answer is no." else: targets = "No, we cannot infer that from the premises." return lib.Example(inputs, targets, example_type, problem)