# Path: smore/common/util.py
# GBFACTOR = float(1 << 30)
# def cal_ent_loc(query_structure, idx):
# def cal_ent_loc_dict(query_name_dict):
# def list2tuple(l):
# def tuple2list(t):
# def parse_time():
# def set_global_seed(seed):
# def eval_tuple(arg_return):
# def flatten_query(queries):
# def construct_graph(base_path, indexified_files):
# def tuple2filterlist(t):
# def achieve_answer_with_constraints(query, ent_in, ent_out, max_to_keep):
# def fill_query(query_structure, ent_in, ent_out, answer, chill=False):
# def sample_negative_bidirectional(query, ent_in, ent_out, nent):
# def download_url(url, folder, log=True):
# def maybe_download_dataset(data_path):
# def extract_zip(path, folder):
# def thread_wrapped_func(func):
#     def decorated_function(*args, **kwargs):
#         def _queue_result():
# def log_metrics(mode, step, metrics):
#     def embed_query_old(queries, query_structure, idx):
#     def embed_query_new(queries, query_structure, idx, all_ent_embedding, ent_idx):
#     def transform_union_query(queries, query_structure):
#     def transform_union_structure(query_structure):
# 
# Path: smore/common/util.py
# GBFACTOR = float(1 << 30)
# def cal_ent_loc(query_structure, idx):
# def cal_ent_loc_dict(query_name_dict):
# def list2tuple(l):
# def tuple2list(t):
# def parse_time():
# def set_global_seed(seed):
# def eval_tuple(arg_return):
# def flatten_query(queries):
# def construct_graph(base_path, indexified_files):
# def tuple2filterlist(t):
# def achieve_answer_with_constraints(query, ent_in, ent_out, max_to_keep):
# def fill_query(query_structure, ent_in, ent_out, answer, chill=False):
# def sample_negative_bidirectional(query, ent_in, ent_out, nent):
# def download_url(url, folder, log=True):
# def maybe_download_dataset(data_path):
# def extract_zip(path, folder):
# def thread_wrapped_func(func):
#     def decorated_function(*args, **kwargs):
#         def _queue_result():
# def log_metrics(mode, step, metrics):
#     def embed_query_old(queries, query_structure, idx):
#     def embed_query_new(queries, query_structure, idx, all_ent_embedding, ent_idx):
#     def transform_union_query(queries, query_structure):
#     def transform_union_structure(query_structure):


from torch.utils.data import Dataset
from smore.common.util import list2tuple, tuple2list, flatten
from collections import defaultdict
from smore.common.util import fill_query, achieve_answer_with_constraints, list2tuple, tuple2list, flatten, flatten_list, sample_negative_bidirectional
import numpy as np
import torch
        query = [_[1] for _ in data]
        query_unflatten = [_[2] for _ in data]
        query_structure = [_[3] for _ in data]
        easy_answers = [_[4] for _ in data]
        hard_answers = [_[5] for _ in data]
        return negative_sample, query, query_unflatten, query_structure, easy_answers, hard_answers


class MultihopTestDataset(TestDataset):
    def __init__(self, data, nentity, nrelation):
        """
        Args:
            data: a list of (query_structure, query, easy_answers, hard_answers, negatives) tuples
        """
        super(MultihopTestDataset, self).__init__(nentity, nrelation)
        self.data = data
        self.test_all = len(data[0][4]) == 0

    def __len__(self):
        return len(self.data)
    
    def __getitem__(self, idx):
        query = self.data[idx][1]
        query_structure = self.data[idx][0]
        easy_answers = self.data[idx][2]
        hard_answers = self.data[idx][3]
        if self.test_all:
            neg_samples = None
        else:
            neg_samples = torch.LongTensor(list(hard_answers) + list(self.data[idx][4]))

# Path: smore/common/util.py
# GBFACTOR = float(1 << 30)
# def cal_ent_loc(query_structure, idx):
# def cal_ent_loc_dict(query_name_dict):
# def list2tuple(l):
# def tuple2list(t):
# def parse_time():
# def set_global_seed(seed):
# def eval_tuple(arg_return):
# def flatten_query(queries):
# def construct_graph(base_path, indexified_files):
# def tuple2filterlist(t):
# def achieve_answer_with_constraints(query, ent_in, ent_out, max_to_keep):
# def fill_query(query_structure, ent_in, ent_out, answer, chill=False):
# def sample_negative_bidirectional(query, ent_in, ent_out, nent):
# def download_url(url, folder, log=True):
# def maybe_download_dataset(data_path):
# def extract_zip(path, folder):
# def thread_wrapped_func(func):
#     def decorated_function(*args, **kwargs):
#         def _queue_result():
# def log_metrics(mode, step, metrics):
#     def embed_query_old(queries, query_structure, idx):
#     def embed_query_new(queries, query_structure, idx, all_ent_embedding, ent_idx):
#     def transform_union_query(queries, query_structure):
#     def transform_union_structure(query_structure):
# 
# Path: smore/common/util.py
# GBFACTOR = float(1 << 30)
# def cal_ent_loc(query_structure, idx):
# def cal_ent_loc_dict(query_name_dict):
# def list2tuple(l):
# def tuple2list(t):
# def parse_time():
# def set_global_seed(seed):
# def eval_tuple(arg_return):
# def flatten_query(queries):
# def construct_graph(base_path, indexified_files):
# def tuple2filterlist(t):
# def achieve_answer_with_constraints(query, ent_in, ent_out, max_to_keep):
# def fill_query(query_structure, ent_in, ent_out, answer, chill=False):
# def sample_negative_bidirectional(query, ent_in, ent_out, nent):
# def download_url(url, folder, log=True):
# def maybe_download_dataset(data_path):
# def extract_zip(path, folder):
# def thread_wrapped_func(func):
#     def decorated_function(*args, **kwargs):
#         def _queue_result():
# def log_metrics(mode, step, metrics):
#     def embed_query_old(queries, query_structure, idx):
#     def embed_query_new(queries, query_structure, idx, all_ent_embedding, ent_idx):
#     def transform_union_query(queries, query_structure):
#     def transform_union_structure(query_structure):


# Path: smore/evaluation/dataloader.py
from torch.utils.data import Dataset
from smore.common.util import list2tuple, tuple2list, flatten
from collections import defaultdict
from smore.common.util import fill_query, achieve_answer_with_constraints, list2tuple, tuple2list, flatten, flatten_list, sample_negative_bidirectional
import numpy as np
import torch

        query = [_[1] for _ in data]
        query_unflatten = [_[2] for _ in data]
        query_structure = [_[3] for _ in data]
        easy_answers = [_[4] for _ in data]
        hard_answers = [_[5] for _ in data]
        return negative_sample, query, query_unflatten, query_structure, easy_answers, hard_answers


class MultihopTestDataset(TestDataset):
    def __init__(self, data, nentity, nrelation):
        """
        Args:
            data: a list of (query_structure, query, easy_answers, hard_answers, negatives) tuples
        """
        super(MultihopTestDataset, self).__init__(nentity, nrelation)
        self.data = data
        self.test_all = len(data[0][4]) == 0

    def __len__(self):
        return len(self.data)
    
    def __getitem__(self, idx):
        query = self.data[idx][1]
        query_structure = self.data[idx][0]
        easy_answers = self.data[idx][2]
        hard_answers = self.data[idx][3]
        if self.test_all:
            neg_samples = None
        else:
            neg_samples = torch.LongTensor(list(hard_answers) + list(self.data[idx][4]))

        return neg_samples, flatten(query), query, query_structure, easy_answers, hard_answers