{"metadata":{"kaggle":{"accelerator":"none","dataSources":[{"sourceId":59575,"databundleVersionId":8060720,"sourceType":"competition"},{"sourceId":8323913,"sourceType":"datasetVersion","datasetId":4944579},{"sourceId":8479599,"sourceType":"datasetVersion","datasetId":4517815},{"sourceId":8962426,"sourceType":"datasetVersion","datasetId":5394510},{"sourceId":8997537,"sourceType":"datasetVersion","datasetId":5419750},{"sourceId":174185912,"sourceType":"kernelVersion"}],"dockerImageVersionId":30698,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.13"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install /kaggle/input/whoosh-wheel-2-7-4/Whoosh-2.7.4-py2.py3-none-any.whl","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_kg_hide-output":false,"execution":{"iopub.status.busy":"2024-07-12T01:29:09.831952Z","iopub.execute_input":"2024-07-12T01:29:09.832369Z","iopub.status.idle":"2024-07-12T01:29:47.594754Z","shell.execute_reply.started":"2024-07-12T01:29:09.832336Z","shell.execute_reply":"2024-07-12T01:29:47.59332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pickle\nfrom dataclasses import dataclass\nfrom pathlib import Path\n\nimport numpy as np\nfrom numpy.typing import NDArray\nimport polars as pl\nfrom tqdm import tqdm\nfrom typing import Any\nimport collections\nimport time\nimport whoosh_utils\nfrom copy import deepcopy\nimport operator\nfrom numba import njit, jit\nfrom numba.typed import List, Dict\nfrom numba.core import types\nimport random\nimport itertools\n\n\nrandom.seed(1000)","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:39:10.761748Z","iopub.execute_input":"2024-07-15T04:39:10.762156Z","iopub.status.idle":"2024-07-15T04:39:45.457035Z","shell.execute_reply.started":"2024-07-15T04:39:10.762121Z","shell.execute_reply":"2024-07-15T04:39:45.455927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://www.kaggle.com/competitions/uspto-explainable-ai/discussion/513097\n@jit(cache=True)\ndef ap50(res: List[str], target_ids: List[str]) -> float:\n    assert len(target_ids) == 50\n    results = List(res)\n    while len(results) < 50:\n        results.append(\"DUMMY\")\n    hit = 0\n    ap = 0\n    for i, result in enumerate(results):\n        if result in target_ids:\n            hit += 1\n        ap += hit / (i + 1)\n    ap /= len(target_ids)\n    return ap","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:39:45.459217Z","iopub.execute_input":"2024-07-15T04:39:45.459767Z","iopub.status.idle":"2024-07-15T04:39:45.471422Z","shell.execute_reply.started":"2024-07-15T04:39:45.459728Z","shell.execute_reply":"2024-07-15T04:39:45.469688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import re\nimport collections\nclass QueryValidator:\n    def validate_query(self, query, parent_has_index=False):\n        index_allowlist = '|'.join(['ab', 'clm', 'cpc', 'detd', 'ti'])\n        index_regexp = re.compile(r'\\.(' + index_allowlist + ')\\.$')\n        inside_paren_regexp = re.compile(r'^(?P<left>\\()(?P<inside>.+)(?P<right>\\)(\\.[a-z]+\\.)?)$')\n\n        def tokenize(text: str):\n            open_paren_regexp = re.compile(r'\\(')\n            close_paren_regexp = re.compile(r'\\)(\\.[a-z]+\\.)?')\n\n            if len(open_paren_regexp.findall(text)) != len(close_paren_regexp.findall(text)):\n                raise UnmatchedParenthesesError('Un-matched parentheses')\n\n            dq = collections.deque(text)\n\n            paren_level = 0\n            curr_token = ''\n            tokens = []\n\n            while len(dq) > 0:\n                curr_char = dq.popleft()\n                curr_token += curr_char\n\n                if curr_char == '(':\n                    paren_level += 1\n                elif curr_char == ')' and paren_level > 1:\n                    paren_level -= 1\n                elif curr_char == ')':\n                    paren_level -= 1\n                    next_char = dq.popleft() if len(dq) > 0 else None\n\n                    if next_char == '.':\n                        curr_token += next_char\n\n                        while len(dq) > 0 and curr_token[-1] != ' ':\n                            curr_token += dq.popleft()\n\n                    tokens.append(curr_token)\n                    curr_token = ''\n                elif len(dq) == 0 or (curr_char == ' ' and paren_level == 0):\n                    tokens.append(curr_token.strip())\n                    curr_token = ''\n\n            return tokens\n\n        tokens = tokenize(query)\n\n        for token in tokens:\n            token = token.strip()\n            num_indexes = len(index_regexp.findall(token))\n\n            if token[-1] == '.' and (parent_has_index or num_indexes == 0):\n                raise InvalidIndexError(f'Invalid index: {token}')\n\n            search = inside_paren_regexp.match(token)\n\n            if search is not None:\n                self.validate_query(search.group('inside'), parent_has_index or num_indexes > 0)\n","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:39:45.472771Z","iopub.execute_input":"2024-07-15T04:39:45.473226Z","iopub.status.idle":"2024-07-15T04:39:45.489811Z","shell.execute_reply.started":"2024-07-15T04:39:45.473187Z","shell.execute_reply":"2024-07-15T04:39:45.488703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import re\nimport whoosh\n\nNUMBER_REGEX = re.compile(r'^(\\d+|\\d{1,3}(,\\d{3})*)(\\.\\d+)?$')\n\nclass NumberFilter(whoosh.analysis.Filter):\n    def __call__(self, tokens):\n        for t in tokens:\n            if not NUMBER_REGEX.match(t.text):\n                yield t\n\nBRS_STOPWORDS = ['an', 'are', 'by', 'for', 'if', 'into', 'is', 'no', 'not', 'of', 'on', 'such',\n        'that', 'the', 'their', 'then', 'there', 'these', 'they', 'this', 'to', 'was', 'will']\nADD_STOPWORDS = [\n 'processing',\n 'machine',\n 'having',\n 'and',\n 'method',\n 'producing',\n 'system',\n 'with',\n 'or',\n 'head',\n 'device',\n 'assembly',\n 'product',\n 'flow',\n 'metal',\n 'storage',\n 'water',\n 'non',\n 'film',\n 'optical',\n 'display',\n 'compositions',\n 'plant',\n 'cell',\n 'providing',\n 'methods',\n 'in',\n 'comprising',\n 'support',\n 'apparatus',\n 'element',\n 'electronic',\n 'module',\n 'mechanism',\n 'memory',\n 'based',\n 'type',\n 'computer',\n 'network',\n 'data',\n 'improved',\n 'container',\n 'image',\n 'content',\n 'monitoring',\n 'using',\n 'fluid',\n 'control',\n 'light',\n 'panel',\n 'integrated',\n 'unit',\n 'use',\n 'from',\n 'manufacturing',\n 'organic',\n 'emitting',\n 'including',\n 'same',\n 'transmission',\n 'power',\n 'drive',\n 'circuit',\n 'controlling',\n 'digital',\n 'wireless',\n 'sensor',\n 'management',\n 'devices',\n 'program',\n 'operating',\n 'interface',\n 'service',\n 'as',\n 'communication',\n 'medium',\n 'liquid',\n 'making',\n 'signal',\n 'related',\n 'treatment',\n 'connector',\n 'fuel',\n 'detecting',\n 'printing',\n 'supply',\n 'vehicle',\n 'systems',\n 'production',\n 'containing',\n 'compounds',\n 'internal',\n 'combustion',\n 'engine',\n 'valve',\n 'heat',\n 'air',\n 'magnetic',\n 'measuring',\n 'high',\n 'low',\n 'structure',\n 'preparing',\n 'forming',\n 'detection',\n 'multiple',\n 'mobile',\n 'recording',\n 'automatic',\n 'portable',\n 'terminal',\n 'access',\n 'application',\n 'video',\n 'time',\n 'frequency',\n 'semiconductor',\n 'thereof',\n 'layer',\n 'antenna',\n 'laser',\n 'information',\n 'multi',\n 'composition',\n 'material',\n 'component',\n 'gas',\n 'pressure',\n 'driving',\n 'imaging',\n 'battery',\n 'therefor',\n 'two',\n 'dynamic',\n 'arrangement',\n 'electric',\n 'motor',\n 'user',\n 'determining',\n 'voltage',\n 'source',\n 'process',\n 'generating',\n 'surface',\n 'preparation',\n 'electrical',\n 'tool',\n 'acid',\n 'substrate'\n]\ncustom_analyzer = whoosh.analysis.StandardAnalyzer(stoplist=BRS_STOPWORDS+ADD_STOPWORDS) | NumberFilter()","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:39:45.492512Z","iopub.execute_input":"2024-07-15T04:39:45.493777Z","iopub.status.idle":"2024-07-15T04:39:45.50824Z","shell.execute_reply.started":"2024-07-15T04:39:45.493741Z","shell.execute_reply":"2024-07-15T04:39:45.507145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pl.read_csv(\"/kaggle/input/uspto-explainable-ai/test.csv\")\nmeta_all = pl.scan_parquet(\"/kaggle/input/uspto-explainable-ai/patent_metadata.parquet\")#.filter(pl.col(\"publication_date\") >= pl.date(1975, 1, 1))\nmeta_title = pl.scan_parquet(\"/kaggle/input/uspto-all-patents-after-1975/all_patents.parquet\").select(pl.exclude(\"abstract\"))\n# test index\nqp = whoosh_utils.get_query_parser()\nqv = QueryValidator()","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:41:25.814659Z","iopub.execute_input":"2024-07-15T04:41:25.815065Z","iopub.status.idle":"2024-07-15T04:41:25.828377Z","shell.execute_reply.started":"2024-07-15T04:41:25.815036Z","shell.execute_reply":"2024-07-15T04:41:25.827135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_title = meta_title.with_columns(\n    pl.col(\"title\").map_elements(lambda x: [xx.text for xx in custom_analyzer(x)]).alias(\"title\")\n)","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:41:53.71357Z","iopub.execute_input":"2024-07-15T04:41:53.713945Z","iopub.status.idle":"2024-07-15T04:41:53.720334Z","shell.execute_reply.started":"2024-07-15T04:41:53.713916Z","shell.execute_reply":"2024-07-15T04:41:53.719166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def time_string(seconds):\n    \"\"\"Returns time in seconds as a string formatted HHHH:MM:SS.\"\"\"\n    s = int(round(seconds))  # round to nearest second\n    h, s = divmod(s, 3600)  # get hours and remainder\n    m, s = divmod(s, 60)  # split remainder into minutes and seconds\n    return \"%4i:%02i:%02i\" % (h, m, s)","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:40:03.797099Z","iopub.execute_input":"2024-07-15T04:40:03.798198Z","iopub.status.idle":"2024-07-15T04:40:03.805449Z","shell.execute_reply.started":"2024-07-15T04:40:03.798147Z","shell.execute_reply":"2024-07-15T04:40:03.804128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_pub = test[:, :].melt().get_column(\"value\").unique()","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:40:05.780187Z","iopub.execute_input":"2024-07-15T04:40:05.780849Z","iopub.status.idle":"2024-07-15T04:40:05.822477Z","shell.execute_reply.started":"2024-07-15T04:40:05.780815Z","shell.execute_reply":"2024-07-15T04:40:05.821373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_meta = meta_all.filter(pl.col(\"publication_number\").is_in(all_pub)).explode(\"cpc_codes\").collect()","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:40:12.53287Z","iopub.execute_input":"2024-07-15T04:40:12.533285Z","iopub.status.idle":"2024-07-15T04:40:17.492416Z","shell.execute_reply.started":"2024-07-15T04:40:12.533252Z","shell.execute_reply":"2024-07-15T04:40:17.491216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_title = meta_title.filter(pl.col(\"publication_number\").is_in(all_pub)).explode(\"title\").collect()","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:41:56.265833Z","iopub.execute_input":"2024-07-15T04:41:56.266217Z","iopub.status.idle":"2024-07-15T04:41:57.475434Z","shell.execute_reply.started":"2024-07-15T04:41:56.266185Z","shell.execute_reply":"2024-07-15T04:41:57.474136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_abstract = pl.read_parquet(\"/kaggle/input/uspto-abstract-exploded-after-1975/abstract_exploded.parquet\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_abstract = meta_abstract.filter(pl.col(\"publication_number\").is_in(all_pub))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_description = pl.read_parquet(\"/kaggle/input/uspto-description-exploded/description_exploded.parquet\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_description = meta_description.filter(pl.col(\"publication_number\").is_in(all_pub))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cpc_all = set(test_meta.select(\"cpc_codes\").to_numpy().squeeze().tolist())","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:42:04.505771Z","iopub.execute_input":"2024-07-15T04:42:04.506159Z","iopub.status.idle":"2024-07-15T04:42:04.868792Z","shell.execute_reply.started":"2024-07-15T04:42:04.50613Z","shell.execute_reply":"2024-07-15T04:42:04.867675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"title_all = set(test_title.select(\"title\").to_numpy().squeeze().tolist())","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:42:04.952046Z","iopub.execute_input":"2024-07-15T04:42:04.953046Z","iopub.status.idle":"2024-07-15T04:42:04.958902Z","shell.execute_reply.started":"2024-07-15T04:42:04.95301Z","shell.execute_reply":"2024-07-15T04:42:04.957685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"abstract_all = set(test_abstract.select(\"abstract\").to_numpy().squeeze().tolist())","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"description_all = set(test_description.select(\"description\").to_numpy().squeeze().tolist())","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_all = meta_all.explode(\"cpc_codes\").filter(pl.col(\"cpc_codes\").is_in(cpc_all)).collect()","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:42:30.357404Z","iopub.execute_input":"2024-07-15T04:42:30.358468Z","iopub.status.idle":"2024-07-15T04:42:59.258064Z","shell.execute_reply.started":"2024-07-15T04:42:30.358429Z","shell.execute_reply":"2024-07-15T04:42:59.256277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_title = meta_title.explode(\"title\").filter(pl.col(\"title\").is_in(title_all)).collect()","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:42:59.260577Z","iopub.execute_input":"2024-07-15T04:42:59.26097Z","iopub.status.idle":"2024-07-15T04:48:52.767415Z","shell.execute_reply.started":"2024-07-15T04:42:59.260924Z","shell.execute_reply":"2024-07-15T04:48:52.766152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_abstract = meta_abstract.filter(pl.col(\"abstract\").is_in(abstract_all))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_description = meta_description.filter(pl.col(\"description\").is_in(description_all))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_pub = set(all_pub.to_numpy().squeeze().tolist())","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results = []\n\nfor ind in tqdm(range(len(test))):\n    start = time.time()\n    \n    target_list = test[ind].to_numpy().flatten()[1:].tolist()\n    target_set = set(target_list)\n    meta_i = test_meta.filter(pl.col(\"publication_number\").is_in(target_set))\n    title_i = test_title.filter(pl.col(\"publication_number\").is_in(target_set))\n    abstract_i = test_abstract.filter(pl.col(\"publication_number\").is_in(target_set))\n    description_i = test_description.filter(pl.col(\"publication_number\").is_in(target_set))\n    if len(meta_i) == 0 and len(title_i) == 0 and len(abstract_i) == 0 and len(description_i) == 0:\n        # append dummy\n        results.append({\"publication_number\": test[ind, \"publication_number\"], \"query\": \"ti:device\"})\n        print(\"\\t Append Dummy\", ind)\n        continue\n    cpc_set = set([cpc for cpc in meta_i.select(\"cpc_codes\").to_numpy().squeeze().tolist() if cpc is not None])\n    meta_all_ = meta_all.filter(pl.col(\"cpc_codes\").is_in(cpc_set))\n    title_set = set([title for title in title_i.select(\"title\").to_numpy().squeeze().tolist() if title is not None])\n    meta_title_ = meta_title.filter(pl.col(\"title\").is_in(title_set))\n    abstract_set = set([abst for abst in abstract_i.select(\"abstract\").to_numpy().squeeze().tolist() if abst is not None])\n    meta_abstract_ = meta_abstract.filter(pl.col(\"abstract\").is_in(abstract_set))\n    description_set = set([detd for detd in description_i.select(\"description\").to_numpy().squeeze().tolist() if detd is not None])\n    meta_description_ = meta_description.filter(pl.col(\"description\").is_in(description_set))\n    pub_dict = dict()\n    token_cnt = 0\n    solution = \"\"\n    pub_added_set_all = set()\n    for cpc in cpc_set:\n        set_tmp = set(meta_all_.filter(pl.col(\"cpc_codes\") == cpc).select(\"publication_number\").to_numpy().squeeze().tolist())\n        set_tmp_test = set_tmp & all_pub\n        if len(set_tmp) >= 10000:\n            continue\n        pub_dict[f\"cpc:{cpc}\"] = set_tmp\n        if len((set_tmp - pub_added_set_all) & target_set) >= max(len(set_tmp - target_set), 1) and len(set_tmp_test - target_set) == 0:\n            pub_added_set_all |= set_tmp\n            if token_cnt == 0:\n                solution += f\"cpc:{cpc}\"\n                token_cnt += 1\n            else:\n                solution += f\" OR cpc:{cpc}\"\n                token_cnt += 2\n                if token_cnt >= 49:\n                    break\n    for title in title_set:\n        set_tmp = set(meta_title_.filter(pl.col(\"title\") == title).select(\"publication_number\").to_numpy().squeeze().tolist())\n        set_tmp_test = set_tmp & all_pub\n        if len(set_tmp) >= 10000:\n            continue\n        pub_dict[f\"ti:{title}\"] = set_tmp\n        if len((set_tmp - pub_added_set_all) & target_set) >= max(len(set_tmp - target_set), 1) and len(set_tmp_test - target_set) == 0:\n            pub_added_set_all |= set_tmp\n            if token_cnt == 0:\n                solution += f\"ti:{title}\"\n                token_cnt += 1\n            else:\n                solution += f\" OR ti:{title}\"\n                token_cnt += 2\n                if token_cnt >= 49:\n                    break\n    for abst in abstract_set:\n        set_tmp = set(meta_abstract_.filter(pl.col(\"abstract\") == abst).select(\"publication_number\").to_numpy().squeeze().tolist())\n        set_tmp_test = set_tmp & all_pub\n        if len(set_tmp) >= 10000:\n            continue\n        pub_dict[f\"ab:{abst}\"] = set_tmp\n        if len((set_tmp - pub_added_set_all) & target_set) >= max(len(set_tmp - target_set), 1) and len(set_tmp_test - target_set) == 0:\n            pub_added_set_all |= set_tmp\n            if token_cnt == 0:\n                solution += f\"ab:{abst}\"\n                token_cnt += 1\n            else:\n                solution += f\" OR ab:{abst}\"\n                token_cnt += 2\n                if token_cnt >= 49:\n                    break\n    for detd in list(description_set)[:min(len(description_set), 500)]:\n        set_tmp = set(meta_description_.filter(pl.col(\"description\") == detd).select(\"publication_number\").to_numpy().squeeze().tolist())\n        set_tmp_test = set_tmp & all_pub\n        if len(set_tmp) >= 10000:\n            continue\n        pub_dict[f\"detd:{detd}\"] = set_tmp\n        if len((set_tmp - pub_added_set_all) & target_set) >= max(len(set_tmp - target_set), 1) and len(set_tmp_test - target_set) == 0:\n            pub_added_set_all |= set_tmp\n            if token_cnt == 0:\n                solution += f\"detd:{detd}\"\n                token_cnt += 1\n            else:\n                solution += f\" OR detd:{detd}\"\n                token_cnt += 2\n                if token_cnt >= 49:\n                    break\n\n    print(\"Candidate Extract Time:\", time_string(time.time() - start))\n    pub_dict = dict({val[0]: val[1] for val in sorted(pub_dict.items(), key=lambda kv: len((kv[1] - pub_added_set_all) & target_set), reverse=True)})\n    pub_comb_dict = dict()\n    for c in itertools.combinations(pub_dict.keys(), 2):\n        cand, another_cand = c\n        pub_0 = pub_dict[cand]\n        pub_1 = pub_dict[another_cand]\n        set_tmp = pub_0 & pub_1\n        set_tmp_test = set_tmp & all_pub\n        if len((set_tmp - pub_added_set_all) & target_set) >= max(len(set_tmp - target_set), 1) and len(set_tmp_test - target_set) == 0:\n            pub_comb_dict[f\"{cand} {another_cand}\"] = set_tmp\n    pub_comb_dict = dict({val[0]: val[1] for val in sorted(pub_comb_dict.items(), key=lambda kv: len((kv[1] - pub_added_set_all) & target_set), reverse=True)})\n    comb_default_dict = collections.defaultdict(list)\n    for cnt in range(min(len(pub_comb_dict), 50)):\n        if len(list(pub_comb_dict.keys())) == 0:\n            break\n        comb = list(pub_comb_dict.keys())[0]\n        pub_added_set_all |= list(pub_comb_dict.values())[0]\n        c1 = comb.split(\" \")[0]\n        c2 = comb.split(\" \")[1]\n        if comb_default_dict[c1]:\n            comb_default_dict[c1].append(c2)\n        elif comb_default_dict[c2]:\n            comb_default_dict[c2].append(c1)\n        else:\n            comb_default_dict[c1].append(c2)\n            comb_default_dict[c2].append(c1)\n        pub_comb_dict = dict({val[0]: val[1] for val in sorted(pub_comb_dict.items(), key=lambda kv: len((kv[1] - pub_added_set_all) & target_set), reverse=True) if len((val[1] - pub_added_set_all) & target_set) > 0})\n    \n    comb_set = set()\n    comb_default_dict = dict({val[0]: val[1] for val in sorted(comb_default_dict.items(), key=lambda kv: len(kv[1]), reverse=True)})\n    for c in comb_default_dict:\n        if c is None:\n            continue\n        cand = c\n        partner_cand_list = []\n        if token_cnt:\n            token_cnt_tmp = 1\n        else:\n            token_cnt_tmp = 0\n        for cc in comb_default_dict[c]:\n            if f\"{c} {cc}\" in comb_set or f\"{cc} {c}\" in comb_set:\n                continue\n            comb_set.add(f\"{c} {cc}\")\n            comb_set.add(f\"{cc} {c}\")\n            partner_cand_list.append(cc)\n            token_cnt_tmp += 2\n            if token_cnt + token_cnt_tmp >= 49:\n                break\n        if partner_cand_list:\n            partner_cand_list_concat = \" OR \".join(partner_cand_list)\n            if token_cnt == 0:\n                if len(partner_cand_list) > 1:\n                    solution_tmp = solution + f\"({cand} ({partner_cand_list_concat}))\"\n                else:\n                    solution_tmp = solution + f\"({cand} {partner_cand_list_concat})\"\n            else:\n                if len(partner_cand_list) > 1:\n                    solution_tmp = solution + f\" OR ({cand} ({partner_cand_list_concat}))\"\n                else:\n                    solution_tmp = solution + f\" OR ({cand} {partner_cand_list_concat})\"\n            if token_cnt + token_cnt_tmp <= 50:\n                solution = solution_tmp\n                token_cnt += token_cnt_tmp\n                if token_cnt > 47:\n                    break\n    \n    print(\"Calculated Tokens:\", token_cnt)\n    print(\"Solution:\", solution)\n    query_cnt = whoosh_utils.count_query_tokens(solution)\n    print(\"Count Query Token:\", query_cnt)\n    if not solution:\n        solution = \"ti:device\"\n    if query_cnt > 50:\n        solution = \"ti:device\"\n    try:\n        qv.validate_query(query=solution)\n    except:\n        print(\"Wrong Query:\", solution)\n        solution = \"ti:device\"\n        \n    # save publication number and query\n    results.append(\n        {\"publication_number\": test[ind, \"publication_number\"], \"query\": solution}\n    )\n    \n    print(\"Time:\", time_string(time.time() - start))","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:48:57.176701Z","iopub.execute_input":"2024-07-15T04:48:57.17709Z","iopub.status.idle":"2024-07-15T04:49:17.403676Z","shell.execute_reply.started":"2024-07-15T04:48:57.177044Z","shell.execute_reply":"2024-07-15T04:49:17.402392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Remove unwanted files and directories that may cause submission errors\n!rm -rf /kaggle/working/*","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:49:23.163926Z","iopub.execute_input":"2024-07-15T04:49:23.164693Z","iopub.status.idle":"2024-07-15T04:49:24.302112Z","shell.execute_reply.started":"2024-07-15T04:49:23.164657Z","shell.execute_reply":"2024-07-15T04:49:24.300409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pl.DataFrame(results)\nsubmission.write_csv(\"submission.csv\")\n\nsubmission","metadata":{"execution":{"iopub.status.busy":"2024-07-15T04:49:24.304395Z","iopub.execute_input":"2024-07-15T04:49:24.304793Z","iopub.status.idle":"2024-07-15T04:49:24.325726Z","shell.execute_reply.started":"2024-07-15T04:49:24.304759Z","shell.execute_reply":"2024-07-15T04:49:24.324593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}