def unknown_relation_generation(current_uid: int, question_template: Dict[str, Any], generated_questions: List[Dict[str, Any]], old_properties_ids: List[str] = None, old_properties: List[str] = None) -> Dict[str, Any]: generated_template = deepcopy(question_template) if old_properties_ids is None: sparql_query = generated_template['sparql_wikidata'] old_properties_ids = questions_generator.get_specific_elements_from_query(sparql_query, [0], "p", "P") old_properties_ids += questions_generator.get_specific_elements_from_query(sparql_query, [0], "pq", "P") questions_generator.relation_generation_common_part(current_uid, generated_template, generated_questions, old_properties_ids, old_properties) unknown_nnqt_question_construction(generated_template) return generated_template
def statement_property_2_relation_3_generation(current_uid: int, question_template: Dict[str, Any], generated_questions: List[Dict[str, Any]]) -> Dict[str, Any]: generated_template = deepcopy(question_template) sparql_query = generated_template['sparql_wikidata'] # Check if there is a filter: if not so the last element is an entity query_contains_filter = 'filter' in sparql_query.lower() if query_contains_filter: old_entities_ids = questions_generator.get_elements_from_query(sparql_query, [0]) # There is only one entity used for both properties old_entities_ids.append(old_entities_ids[0]) else: old_entities_ids = questions_generator.get_elements_from_query(sparql_query, [0, 1]) old_properties_ids = [questions_generator.get_specific_elements_from_query(sparql_query, [0], "p", "P")[0]] # The order is inverted because in the queries of this case the first entity is linked to the second property and the second entity is linked to the first property old_properties_ids.insert(0, questions_generator.get_specific_elements_from_query(sparql_query, [0], "pq", "P")[0]) old_answer = next(iter(questions_generator.get_sparql_query_results(sparql_query)['results']['bindings'][0].values()))['value'].split("/")[-1] # Find answer filter and type old_answer_filter, element_type = questions_generator.get_filter_from_element(old_answer, "obj", "s") # The first query is the same for both cases if element_type == questions_generator.ElementType.entity: first_query = "select distinct ?ans where {?sbj ?rel ?s . ?s ?ans wd:" + old_answer + " . ?sbj wdt:|rel_entity_type| wd:|entity_type| . FILTER (" + \ old_answer_filter + " && ?ans not in (pq:|old_property_id|))} LIMIT 20" else: # The answer is not an entity first_query = "SELECT distinct ?ans WHERE {?sbj ?rel ?s . ?s ?ans ?obj . ?sbj wdt:|rel_entity_type| wd:|entity_type| . FILTER (" + old_answer_filter + \ " && ?ans not in (pq:|old_property_id|))} LIMIT 10" if query_contains_filter: # Find qualifier value, substituting the answer variable with the corresponding variable answer_var_name = re.findall(r'SELECT (\?\w*) WHERE', sparql_query, re.IGNORECASE)[0] qualifier_var_name = re.findall(old_properties_ids[1] + r' (\?\w*) filter', sparql_query, re.IGNORECASE)[0] sparql_query_qualifier = sparql_query.replace(answer_var_name, qualifier_var_name, 1) old_qualifier_value = next(iter(questions_generator.get_sparql_query_results(sparql_query_qualifier)['results']['bindings'][0].values()))['value'].split("/")[-1] # Find qualifier filter old_qualifier_filter, _ = questions_generator.get_filter_from_element(old_qualifier_value, "x", "s") # Since the answer is not an entity, in this case the queries results link the known entity to a value of the same type of the original one: the type is # defined through the corresponding filter. Besides the second query accepts only properties that are "qualifiers", so that are represented with the "p" prefix found, old_properties = questions_generator.relation_3_generation_common_part(current_uid, generated_template, generated_questions, old_entities_ids, old_properties_ids, \ [first_query, "SELECT distinct ?ans WHERE { ?sbj ?ans ?s . ?s ?rel2 ?x . ?sbj wdt:|rel_entity_type| wd:|entity_type| . FILTER (" + old_qualifier_filter + \ " && ?ans not in (p:|old_property_id|)) } LIMIT 10"], ["pq", ""]) else: # The first query is identical to the other case, the second instead becomes more normal found, old_properties = questions_generator.relation_3_generation_common_part(current_uid, generated_template, generated_questions, old_entities_ids, old_properties_ids, \ [first_query, "select distinct ?ans where {wd:" + old_entities_ids[0] + " ?ans ?s . ?s ?rel2 ?obj . ?obj wdt:|rel_entity_type| wd:|entity_type| . FILTER " + \ "(REGEX(STR(?s), \"Q(\\\\d+)-\") && ?ans not in (p:|old_property_id|))} LIMIT 20"], ["pq", ""]) if not found: # There aren't valid candidates, so try with "relation_2" function return statement_property_2_relation_2_generation(current_uid, generated_template, generated_questions, old_properties_ids, old_properties) else: statement_property_2_nnqt_question_construction(generated_template) return generated_template
def unknown_relation_2_generation(current_uid: int, question_template: Dict[str, Any], generated_questions: List[Dict[str, Any]], old_properties_ids: List[str] = None, old_properties: List[str] = None) -> Dict[str, Any]: generated_template = deepcopy(question_template) if old_properties_ids is None: sparql_query = generated_template['sparql_wikidata'] old_properties_ids = questions_generator.get_specific_elements_from_query(sparql_query, [0], "p", "P") old_properties_ids += questions_generator.get_specific_elements_from_query(sparql_query, [0], "pq", "P") found, old_properties = questions_generator.relation_2_generation_common_part(current_uid, generated_template, generated_questions, old_properties_ids, old_properties) if not found: # There aren't valid candidates, so try with a random property return unknown_relation_generation(current_uid, question_template, generated_questions, old_properties_ids, old_properties) else: unknown_nnqt_question_construction(generated_template) return generated_template
def unknown_2_relation_3_generation(current_uid: int, question_template: Dict[str, Any], generated_questions: List[Dict[str, Any]]) -> Dict[str, Any]: generated_template = deepcopy(question_template) sparql_query = generated_template['sparql_wikidata'] old_entities_ids = questions_generator.get_elements_from_query(sparql_query, [0, 1]) # The first entity is used for the last two properties old_entities_ids.reverse() old_entities_ids.append(old_entities_ids[0]) old_properties_ids = questions_generator.get_specific_elements_from_query(sparql_query, [0], "p", "P") old_properties_ids += questions_generator.get_specific_elements_from_query(sparql_query, [0, 1], "pq", "P") # Answers are inverted old_answers = iter(questions_generator.get_sparql_query_results(sparql_query)['results']['bindings'][0].values()) old_answer_2 = next(old_answers)['value'].split("/")[-1] old_answer_1 = next(old_answers)['value'].split("/")[-1] # Find answers filter and type old_answer_1_filter, element_type_1 = questions_generator.get_filter_from_element(old_answer_1, "obj", "s") old_answer_2_filter, element_type_2 = questions_generator.get_filter_from_element(old_answer_2, "obj", "s") # These two queries are identical except for the associated property and the answer filter if element_type_1 == questions_generator.ElementType.entity: second_query = "select distinct ?ans where {?sbj ?rel ?s . ?s ?ans wd:" + old_answer_1 + " . ?sbj wdt:|rel_entity_type| wd:|entity_type| . FILTER (" + \ old_answer_1_filter + " && ?ans not in (pq:|old_property_id|))} LIMIT 20" else: # If the answer is not an entity, in this case the queries results link the known entity to a value of the same type of the original one: the type is # defined through the corresponding filter second_query = "SELECT distinct ?ans WHERE {?sbj ?rel ?s . ?s ?ans ?obj . ?sbj wdt:|rel_entity_type| wd:|entity_type| . FILTER (" + old_answer_1_filter + \ " && ?ans not in (pq:|old_property_id|))} LIMIT 10" if element_type_2 == questions_generator.ElementType.entity: third_query = "select distinct ?ans where {?sbj ?rel ?s . ?s ?ans wd:" + old_answer_2 + " . ?sbj wdt:|rel_entity_type| wd:|entity_type| . FILTER (" + \ old_answer_2_filter + " && ?ans not in (pq:|old_property_id|))} LIMIT 20" else: # If the answer is not an entity, in this case the queries results link the known entity to a value of the same type of the original one: the type is # defined through the corresponding filter third_query = "SELECT distinct ?ans WHERE {?sbj ?rel ?s . ?s ?ans ?obj . ?sbj wdt:|rel_entity_type| wd:|entity_type| . FILTER (" + old_answer_2_filter + \ " && ?ans not in (pq:|old_property_id|))} LIMIT 10" # The second query accepts only properties that are "qualifiers", so that are represented with the "pq" prefix found, old_properties = questions_generator.relation_3_generation_common_part(current_uid, generated_template, generated_questions, old_entities_ids, old_properties_ids, \ ["select distinct ?ans where {wd:" + old_entities_ids[1] + " ?ans ?s . ?s ?rel2 ?obj . ?obj wdt:|rel_entity_type| wd:|entity_type| . FILTER " + \ "(REGEX(STR(?s), \"Q(\\\\d+)-\") && ?ans not in (p:|old_property_id|))} LIMIT 20", second_query, third_query], ["", "pq", "pq"]) if not found: # There aren't valid candidates, so try with "relation_2" function return unknown_2_relation_2_generation(current_uid, generated_template, generated_questions, old_properties_ids, old_properties) else: unknown_2_nnqt_question_construction(generated_template) return generated_template