class_docstr: This class extract relations, objects or triplets from Wikidata HDT file.
class_docstr_tok: ["This","class","extract","relations",",","objects","or","triplets","from","Wikidata","HDT","file","."]
docstr: Let us consider an example of the question "What is the deepest lake in Russia?"
  with the corresponding SPARQL query            
  "SELECT ?ent WHERE { ?ent wdt:P31 wd:T1 . ?ent wdt:R1 ?obj . ?ent wdt:R2 wd:E1 } ORDER BY ASC(?obj) LIMIT 5"
  
  arguments:
      what_return: ["?obj"]
      query_seq: [["?ent", "http://www.wikidata.org/prop/direct/P17", "http://www.wikidata.org/entity/Q159"]
                  ["?ent", "http://www.wikidata.org/prop/direct/P31", "http://www.wikidata.org/entity/Q23397"],
                  ["?ent", "http://www.wikidata.org/prop/direct/P4511", "?obj"]]
      filter_info: []
      order_info: order_info(variable='?obj', sorting_order='asc')
docstr_tok: ["Let","us","consider","an","example","of","the","question","``","What","is","the","deepest","lake","in","Russia","?","''","with","the","corresponding","SPARQL","query","''","SELECT","?","ent","WHERE","{","?","ent","wdt",":","P31","wd",":","T1",".","?","ent","wdt",":","R1","?","obj",".","?","ent","wdt",":","R2","wd",":","E1","}","ORDER","BY","ASC","(","?","obj",")","LIMIT","5","''","arguments",":","what_return",":","[","``","?","obj","''","]","query_seq",":","[","[","``","?","ent","''",",","``","http",":","\/\/www.wikidata.org\/prop\/direct\/P17","''",",","``","http",":","\/\/www.wikidata.org\/entity\/Q159","''","]","[","``","?","ent","''",",","``","http",":","\/\/www.wikidata.org\/prop\/direct\/P31","''",",","``","http",":","\/\/www.wikidata.org\/entity\/Q23397","''","]",",","[","``","?","ent","''",",","``","http",":","\/\/www.wikidata.org\/prop\/direct\/P4511","''",",","``","?","obj","''","]","]","filter_info",":","[","]","order_info",":","order_info","(","variable=","'","?","obj","'",",","sorting_order='asc","'",")"]
code: def execute(
      self,
      what_return: List[str],
      rels_from_query: List[str],
      query_seq: List[List[str]],
      filter_info: List[Tuple[str]] = None,
      order_info: namedtuple = None,
      answer_types: List[str] = None,
      rel_types: List[str] = None,
  ):
      """
      Let us consider an example of the question "What is the deepest lake in Russia?"
      with the corresponding SPARQL query
      "SELECT ?ent WHERE { ?ent wdt:P31 wd:T1 . ?ent wdt:R1 ?obj . ?ent wdt:R2 wd:E1 } ORDER BY ASC(?obj) LIMIT 5"
  
      arguments:
          what_return: ["?obj"]
          query_seq: [["?ent", "http://www.wikidata.org/prop/direct/P17", "http://www.wikidata.org/entity/Q159"]
                      ["?ent", "http://www.wikidata.org/prop/direct/P31", "http://www.wikidata.org/entity/Q23397"],
                      ["?ent", "http://www.wikidata.org/prop/direct/P4511", "?obj"]]
          filter_info: []
          order_info: order_info(variable='?obj', sorting_order='asc')
      """
      extended_combs = []
      answers, found_rels, found_combs = [], [], []
  
      for n, (query, rel_type) in enumerate(zip(query_seq, rel_types)):
          unknown_elem_positions = [
              (pos, elem)
              for pos, elem in enumerate(query)
              if elem.startswith("?")
          ]
          """
                  n = 0, query = ["?ent", "http://www.wikidata.org/prop/direct/P17",
                                  "http://www.wikidata.org/entity/Q159"]
                         unknown_elem_positions = ["?ent"]
                  n = 1, query = ["?ent", "http://www.wikidata.org/prop/direct/P31",
                                  "http://www.wikidata.org/entity/Q23397"]
                         unknown_elem_positions = [(0, "?ent")]
                  n = 2, query = ["?ent", "http://www.wikidata.org/prop/direct/P4511", "?obj"]
                         unknown_elem_positions = [(0, "?ent"), (2, "?obj")]
              """
          if n == 0:
              combs, triplets = self.search(
                  query, unknown_elem_positions, rel_type
              )
              # combs = [{"?ent": "http://www.wikidata.org/entity/Q5513"}, ...]
          else:
              if combs:
                  known_elements = []
                  extended_combs = []
                  if query[0].startswith("?"):
                      for elem in query:
                          if elem in combs[0].keys():
                              known_elements.append(elem)
                      for comb in combs:
                          """
                          n = 1
                          query = ["?ent", "http://www.wikidata.org/prop/direct/P31",
                                                                      "http://www.wikidata.org/entity/Q23397"]
                          comb = {"?ent": "http://www.wikidata.org/entity/Q5513"}
                          known_elements = ["?ent"], known_values = ["http://www.wikidata.org/entity/Q5513"]
                          filled_query = ["http://www.wikidata.org/entity/Q5513",
                                          "http://www.wikidata.org/prop/direct/P31",
                                          "http://www.wikidata.org/entity/Q23397"]
                          new_combs = [["http://www.wikidata.org/entity/Q5513",
                                        "http://www.wikidata.org/prop/direct/P31",
                                        "http://www.wikidata.org/entity/Q23397"], ...]
                          extended_combs = [{"?ent": "http://www.wikidata.org/entity/Q5513"}, ...]
                          """
                          if comb:
                              known_values = [
                                  comb[known_elem]
                                  for known_elem in known_elements
                              ]
                              for known_elem, known_value in zip(
                                  known_elements, known_values
                              ):
                                  filled_query = [
                                      elem.replace(
                                          known_elem, known_value
                                      )
                                      for elem in query
                                  ]
                                  new_combs, triplets = self.search(
                                      filled_query,
                                      unknown_elem_positions,
                                      rel_type,
                                  )
                                  for new_comb in new_combs:
                                      extended_combs.append(
                                          self.merge_combs(
                                              comb, new_comb
                                          )
                                      )
                  else:
                      new_combs, triplets = self.search(
                          query, unknown_elem_positions, rel_type
                      )
                      for comb in combs:
                          for new_comb in new_combs:
                              extended_combs.append(
                                  self.merge_combs(comb, new_comb)
                              )
              combs = extended_combs
  
      is_boolean = self.define_is_boolean(query_seq)
      if combs or is_boolean:
          if filter_info:
              for filter_elem, filter_value in filter_info:
                  if filter_value == "qualifier":
                      filter_value = "wpq/"
                  combs = [
                      comb
                      for comb in combs
                      if filter_value in comb[filter_elem]
                  ]
  
          if (
              order_info
              and not isinstance(order_info, list)
              and order_info.variable is not None
          ):
              reverse = (
                  True if order_info.sorting_order == "desc" else False
              )
              sort_elem = order_info.variable
              if combs and "?p" in combs[0]:
                  rel_combs = {}
                  for comb in combs:
                      if comb["?p"] not in rel_combs:
                          rel_combs[comb["?p"]] = []
                      rel_combs[comb["?p"]].append(comb)
                  rel_combs_list = rel_combs.values()
              else:
                  rel_combs_list = [combs]
              new_rel_combs_list = []
              for rel_combs in rel_combs_list:
                  new_rel_combs = []
                  for rel_comb in rel_combs:
                      value_str = (
                          rel_comb[sort_elem].split("^^")[0].strip('"+')
                      )
                      fnd_date = re.findall(
                          r"[\d]{3,4}-[\d]{1,2}-[\d]{1,2}", value_str
                      )
                      fnd_num = re.findall(
                          r"([\d]+)\.([\d]+)", value_str
                      )
                      if fnd_date:
                          rel_comb[sort_elem] = fnd_date[0]
                      elif fnd_num or value_str.isdigit():
                          rel_comb[sort_elem] = float(value_str)
                      new_rel_combs.append(rel_comb)
                  new_rel_combs = [
                      (elem, n) for n, elem in enumerate(new_rel_combs)
                  ]
                  new_rel_combs = sorted(
                      new_rel_combs,
                      key=lambda x: (x[0][sort_elem], x[1]),
                      reverse=reverse,
                  )
                  new_rel_combs = [elem[0] for elem in new_rel_combs]
                  new_rel_combs_list.append(new_rel_combs)
              combs = [
                  new_rel_combs[0]
                  for new_rel_combs in new_rel_combs_list
              ]
  
          if what_return and what_return[-1].startswith("count"):
              answers = [[len(combs)]]
          else:
              answers = [
                  [elem[key] for key in what_return if key in elem]
                  for elem in combs
              ]
  
          if answer_types:
              if list(answer_types) == ["date"]:
                  answers = [
                      [
                          entity
                          for entity in answer
                          if re.findall(
                              r"[\d]{3,4}-[\d]{1,2}-[\d]{1,2}", entity
                          )
                      ]
                      for answer in answers
                  ]
              elif list(answer_types) == ["not_date"]:
                  answers = [
                      [
                          entity
                          for entity in answer
                          if not re.findall(
                              r"[\d]{3,4}-[\d]{1,2}-[\d]{1,2}", entity
                          )
                      ]
                      for answer in answers
                  ]
              else:
                  answer_types = set(answer_types)
                  answers = [
                      [
                          entity
                          for entity in answer
                          if answer_types.intersection(
                              self.find_types(entity)
                          )
                      ]
                      for answer in answers
                  ]
          if is_boolean:
              answers = [["Yes" if len(triplets) > 0 else "No"]]
          found_rels = [
              [elem[key] for key in rels_from_query if key in elem]
              for elem in combs
          ]
          ans_rels_combs = [
              (answer, rel, comb)
              for answer, rel, comb in zip(answers, found_rels, combs)
              if any([entity for entity in answer])
          ]
          answers = [elem[0] for elem in ans_rels_combs]
          found_rels = [elem[1] for elem in ans_rels_combs]
          found_combs = [elem[2] for elem in ans_rels_combs]
  
      return answers, found_rels, found_combs
  
imports: import datetime
  import re
  from collections import namedtuple
  from logging import getLogger
  from typing import List, Tuple, Dict, Any, Union
  from hdt import HDTDocument
  from deeppavlov.core.commands.utils import expand_path
  from deeppavlov.core.common.file import load_pickle, read_json
  from deeppavlov.core.common.registry import register
label_desc: Use image node_id 4 for calling the WikiParser obj's underlying member method code with example usage: obj.execute(what_return, rels_from_query, query_seq, filter_info, order_info, answer_types, rel_types) and returns: answers,  found_rels,  found_combs