Xin-Rui commited on
Commit
a80200a
·
verified ·
1 Parent(s): fa64422

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. .gitignore +185 -0
  3. Chain_Of_Thought_Metric/length_of_answer.py +146 -0
  4. Chain_Of_Thought_Metric/metric.py +172 -0
  5. Chain_Of_Thought_Metric/tools.py +80 -0
  6. Following_Budget_Ratio.png +0 -0
  7. GPU_hunter.py +57 -0
  8. LICENSE +21 -0
  9. README.md +52 -0
  10. api_test.py +448 -0
  11. copy_backup.py +36 -0
  12. data/aime24/aime24.parquet +3 -0
  13. data/amc23/amc23.parquet +3 -0
  14. data/carp_en/demo.json +8 -0
  15. data/math500/math500_RL.parquet +3 -0
  16. data/math500_answer_prompt/get_answer_prompt.py +24 -0
  17. data/minerva_math/README.md +2 -0
  18. data/olympiadbench/test.json +0 -0
  19. data/trans_parquet.py +28 -0
  20. data_loader.py +85 -0
  21. eval_tools.py +470 -0
  22. evaluate.py +117 -0
  23. examples.py +378 -0
  24. grader.py +395 -0
  25. latex2sympy/.coveragerc +31 -0
  26. latex2sympy/.gitignore +132 -0
  27. latex2sympy/LICENSE.txt +21 -0
  28. latex2sympy/PS.g4 +638 -0
  29. latex2sympy/README.md +196 -0
  30. latex2sympy/__init__.py +1 -0
  31. latex2sympy/antlr-4.11.1-complete.jar +3 -0
  32. latex2sympy/asciimath_printer.py +50 -0
  33. latex2sympy/description.txt +152 -0
  34. latex2sympy/dev-requirements.in +8 -0
  35. latex2sympy/dev-requirements.txt +60 -0
  36. latex2sympy/gen/PS.interp +462 -0
  37. latex2sympy/gen/PS.tokens +357 -0
  38. latex2sympy/gen/PSLexer.interp +0 -0
  39. latex2sympy/gen/PSLexer.py +0 -0
  40. latex2sympy/gen/PSLexer.tokens +357 -0
  41. latex2sympy/gen/PSListener.py +573 -0
  42. latex2sympy/gen/PSParser.py +0 -0
  43. latex2sympy/gen/__init__.py +0 -0
  44. latex2sympy/icon.png +0 -0
  45. latex2sympy/latex2sympy2.py +1162 -0
  46. latex2sympy/requirements.in +2 -0
  47. latex2sympy/requirements.txt +12 -0
  48. latex2sympy/sandbox/linalg_equations.py +10 -0
  49. latex2sympy/sandbox/linalg_span.py +19 -0
  50. latex2sympy/sandbox/matrix.py +46 -0
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ latex2sympy/antlr-4.11.1-complete.jar filter=lfs diff=lfs merge=lfs -text
37
+ math500_accuracy_vs_length.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
116
+ .pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121
+ __pypackages__/
122
+
123
+ # Celery stuff
124
+ celerybeat-schedule
125
+ celerybeat.pid
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .venv
133
+ env/
134
+ venv/
135
+ ENV/
136
+ env.bak/
137
+ venv.bak/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # PyCharm
164
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
167
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
+ #.idea/
169
+
170
+ # PyPI configuration file
171
+ .pypirc
172
+
173
+ # outputs
174
+ outputs/
175
+ checkpoints/
176
+ wandb/
177
+ tensorboard_log/
178
+ *.jsonl
179
+ trained/
180
+ training/
181
+ *.log
182
+ MODEL-*/
183
+ wrong_model/*
184
+ MODEL*/
185
+ MODEL**/
Chain_Of_Thought_Metric/length_of_answer.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ from transformers import AutoTokenizer
4
+ import json
5
+ import matplotlib.pyplot as plt
6
+
7
+ # 父文件夹路径
8
+ parent_folder = "/mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation"
9
+ pattern = re.compile(r"MODEL-.*-TIP-.*-STAGE-add-DATA-.*")
10
+
11
+ entry_list = []
12
+ setting_names = []
13
+ # tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen1.5-1.8B", trust_remote_code=True) # 使用合适的tokenizer
14
+ tokenizer = AutoTokenizer.from_pretrained("/mnt/lyc/wuxinrui/LLaMA-Factory/TCMv4_8ratio/1_5B_TCMv4_8ratio_models/models", trust_remote_code=True)
15
+
16
+ def calculate_token_length(text):
17
+ """计算文本的token长度"""
18
+ tokens = tokenizer(text)['input_ids']
19
+ return len(tokens)
20
+
21
+ if __name__ == "__main__":
22
+ for folder in os.listdir(parent_folder):
23
+ # if pattern.match(folder):
24
+ if folder == "MODEL-7B_TCMv4_8ratio_v1_global_step_180-TIP-8ratio-STAGE-2-DATA-math500":
25
+ entry_list.append(os.path.join(parent_folder, folder))
26
+ setting_names.append(folder)
27
+
28
+ for entry, setting_name in zip(entry_list, setting_names):
29
+ token_length_metrics = []
30
+ final_answer_metrics = []
31
+
32
+ for sub_entry in os.listdir(entry):
33
+ if not os.path.isdir(os.path.join(entry, sub_entry)):
34
+ continue
35
+
36
+ for root, dirs, files in os.walk(os.path.join(entry, sub_entry)):
37
+ for file in files:
38
+ if "metrics" in file:
39
+ continue
40
+
41
+ cot_answer_path = os.path.join(root, file)
42
+
43
+ with open(cot_answer_path, "r") as f:
44
+ token_length_data = {}
45
+ final_answer_data = {}
46
+ budget_length = int(sub_entry)
47
+ token_length_data['budget_length'] = budget_length
48
+ final_answer_data['budget_length'] = budget_length
49
+ total_tokens = 0
50
+ answer_count = 0
51
+ single_final_answer_count = 0
52
+ multiple_final_answer_count = 0
53
+ total_delta_length = 0 # 新增:总长度差
54
+ valid_delta_count = 0 # 新增:有效计数(长度小于budget的)
55
+
56
+ for line in f:
57
+ data = json.loads(line)
58
+ answer_text = data['code'][0]
59
+ token_length = calculate_token_length(answer_text)
60
+ total_tokens += token_length
61
+ answer_count += 1
62
+
63
+ # 计算delta_length(新增部分)
64
+ if token_length < budget_length:
65
+ delta = budget_length - token_length
66
+ total_delta_length += delta
67
+ valid_delta_count += 1
68
+
69
+ # 判断 **Final Answer** 的数量
70
+ first_match = answer_text.find("</think>")
71
+ if first_match != -1:
72
+ modified_text = answer_text[:first_match] + answer_text[first_match + len("</think>"):]
73
+ second_match = modified_text.find("</think>")
74
+
75
+ if second_match == -1:
76
+ single_final_answer_count += 1
77
+ else:
78
+ multiple_final_answer_count += 1
79
+
80
+ avg_token_length = total_tokens / answer_count if answer_count > 0 else 0
81
+ token_length_data['avg_token_length'] = avg_token_length
82
+ token_length_data['total_tokens'] = total_tokens
83
+
84
+ # 新增:计算平均delta_length
85
+ avg_delta_length = total_delta_length / valid_delta_count if valid_delta_count > 0 else 0
86
+ token_length_data['avg_delta_length'] = avg_delta_length
87
+ token_length_data['avg_delta_length/BUDGET'] = avg_delta_length / token_length_data['budget_length']
88
+ token_length_data['valid_delta_count'] = valid_delta_count
89
+
90
+ token_length_metrics.append(token_length_data)
91
+
92
+ final_answer_data['single_final_answer_count'] = single_final_answer_count
93
+ final_answer_data['multiple_final_answer_count'] = multiple_final_answer_count
94
+ final_answer_data['total_answer_count'] = answer_count
95
+ final_answer_data['multiple_final_answer_ratio'] = multiple_final_answer_count / answer_count if answer_count > 0 else 0
96
+ final_answer_metrics.append(final_answer_data)
97
+
98
+ # 按budget_length排序
99
+ token_length_metrics.sort(key=lambda x: x['budget_length'])
100
+ final_answer_metrics.sort(key=lambda x: x['budget_length'])
101
+
102
+ # 绘制图表 - 平均token长度
103
+ fig, ax = plt.subplots(figsize=(10, 6))
104
+ budget_lengths = [data['budget_length'] for data in token_length_metrics]
105
+ avg_lengths = [data['avg_token_length'] for data in token_length_metrics]
106
+
107
+ length_csv = os.path.join(entry, "token_length_metrics.csv")
108
+ with open(length_csv, "w") as f:
109
+ f.write("budget_length,avg_token_length,total_tokens,avg_delta_length,valid_delta_count, avg_delta_length/BUDGET]\n")
110
+ for data in token_length_metrics:
111
+ f.write(f"{data['budget_length']},{data['avg_token_length']},{data['total_tokens']},{data['avg_delta_length']},{data['valid_delta_count']}, {data['avg_delta_length/BUDGET']}\n")
112
+
113
+ ax.plot(budget_lengths, avg_lengths, marker='o', color='blue', linewidth=2)
114
+ ax.set_title(f"Average Token Length by Budget Length - {setting_name}")
115
+ ax.set_xlabel('Budget Length')
116
+ ax.set_ylabel('Average Token Length')
117
+ ax.grid(True)
118
+
119
+ plt.tight_layout()
120
+ pic_name = os.path.join(entry, "token_length_metrics.png")
121
+ plt.savefig(pic_name, dpi=300)
122
+ print(f"Saved figure as {pic_name}")
123
+ plt.close()
124
+
125
+ # 新增:绘制delta_length图表
126
+ fig, ax = plt.subplots(figsize=(10, 6))
127
+ avg_deltas = [data['avg_delta_length'] for data in token_length_metrics]
128
+
129
+ ax.plot(budget_lengths, avg_deltas, marker='o', color='green', linewidth=2)
130
+ ax.set_title(f"Average Delta Length by Budget Length - {setting_name}")
131
+ ax.set_xlabel('Budget Length')
132
+ ax.set_ylabel('Average Delta Length (budget - actual)')
133
+ ax.grid(True)
134
+
135
+ plt.tight_layout()
136
+ delta_pic_name = os.path.join(entry, "delta_length_metrics.png")
137
+ plt.savefig(delta_pic_name, dpi=300)
138
+ print(f"Saved delta figure as {delta_pic_name}")
139
+ plt.close()
140
+
141
+ # 保存 **Final Answer** 的统计结果
142
+ final_answer_csv = os.path.join(entry, "final_answer_metrics.csv")
143
+ with open(final_answer_csv, "w") as f:
144
+ f.write("budget_length,single_final_answer_count,multiple_final_answer_count,total_answer_count,multiple_final_answer_ratio\n")
145
+ for data in final_answer_metrics:
146
+ f.write(f"{data['budget_length']},{data['single_final_answer_count']},{data['multiple_final_answer_count']},{data['total_answer_count']},{data['multiple_final_answer_ratio']}\n")
Chain_Of_Thought_Metric/metric.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ from transformers import AutoTokenizer
4
+ import json
5
+ import matplotlib.pyplot as plt
6
+ # from .Chain_Of_Thought_Metric.tools import *
7
+
8
+ # 父文件夹路径
9
+ parent_folder = "/mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation"
10
+
11
+ # pattern = re.compile(r"MODEL-.*-TIP-.*-STAGE-\d+")
12
+ pattern = re.compile(r"MODEL-.*-TIP-.*-STAGE-add-DATA-.*")
13
+
14
+ entry_list = []
15
+ setting_names = []
16
+ # tokenizer = AutoTokenizer.from_pretrained("/data05/wuxinrui/LLaMA-Factory/DS-distill-QWen-1_5B_TCM/models", trust_remote_code=True)
17
+
18
+ for folder in os.listdir(parent_folder):
19
+ # if pattern.match(folder):
20
+ if folder == "MODEL-TCMv4_ablation_v1_step_77_reward_0.824-TIP-withoutremaining-STAGE-2-DATA-math500":
21
+ entry_list.append(os.path.join(parent_folder, folder))
22
+ setting_names.append(folder)
23
+
24
+ def is_balanced(s: str) -> bool:
25
+ """验证大括号是否成对且正确嵌套"""
26
+ stack = 0
27
+ for char in s:
28
+ if char == "{":
29
+ stack += 1
30
+ elif char == "}":
31
+ stack -= 1
32
+ if stack < 0:
33
+ return False
34
+ return stack == 0
35
+
36
+
37
+ def find_sequence(array, sequence):
38
+ sequence_length = len(sequence)
39
+ array_length = len(array)
40
+ start_positions = []
41
+
42
+ for i in range(array_length - sequence_length + 1):
43
+ if array[i:i+sequence_length] == sequence:
44
+ start_positions.append(i)
45
+
46
+ return start_positions
47
+
48
+
49
+ def get_final_answer_status(anwser):
50
+ find_string = "**Final Answer**\\boxed"
51
+ # find_string = "**Final Answer**"
52
+ sequence = [334, 19357, 21806, 334, 59, 79075]
53
+
54
+ Thought_END = 0
55
+ START = 0
56
+ END = 0
57
+ if not find_string in anwser:
58
+ return Thought_END, START, END
59
+
60
+ else:
61
+ Thought_END = 1
62
+
63
+ # #G ---------------- 匹配正反大括号
64
+ # start_idx = anwser.find('**Final Answer**\\boxed{')
65
+ # stack = 1
66
+ # end_idx = start_idx + len('**Final Answer**\\boxed{')
67
+ # while end_idx < len(anwser) and stack > 0:
68
+ # if anwser[end_idx] == "{":
69
+ # stack += 1
70
+ # elif anwser[end_idx] == "}":
71
+ # stack -= 1
72
+ # end_idx += 1
73
+ # if stack == 0 and is_balanced(anwser[start_idx:end_idx]):
74
+ # Thought_END = 1
75
+ # # tokenized_answer = tokenizer(anwser)['input_ids']
76
+ # # #G 找出结束时的token位置
77
+ # # start_positions = find_sequence(tokenized_answer, sequence)
78
+ # else:
79
+ # Thought_END = 0
80
+ #G -----------------
81
+
82
+ return Thought_END, START, END
83
+
84
+ def calculate_ratios(thinking_ended, answer_correct):
85
+ # 初始化计数器
86
+ ET_count = 0
87
+ total_count = len(thinking_ended)
88
+ EF_count = 0
89
+ OT_count = 0
90
+
91
+ # 遍历列表
92
+ for i in range(total_count):
93
+ if thinking_ended[i] == 1 and answer_correct[i] == 1:
94
+ ET_count += 1
95
+ if thinking_ended[i] == 1 and answer_correct[i] == 0:
96
+ EF_count += 1
97
+ if thinking_ended[i] == 0 and answer_correct[i] == 1:
98
+ OT_count += 1
99
+
100
+ # 计算比值
101
+ ET_ratio = ET_count / total_count if total_count > 0 else 0
102
+ EF_ratio = EF_count / total_count if total_count > 0 else 0
103
+ OT_ratio = OT_count / total_count if total_count > 0 else 0
104
+
105
+ acc = sum(thinking_ended) / total_count if total_count > 0 else 0
106
+
107
+ return ET_ratio, EF_ratio, OT_ratio, acc
108
+
109
+ if __name__ == "__main__":
110
+
111
+ for entry, setting_name in zip(entry_list, setting_names):
112
+ CoT_metric_one_setting = []
113
+ for sub_entry in os.listdir(entry):
114
+ if not os.path.isdir(os.path.join(entry, sub_entry)):
115
+ continue
116
+ #G 对于每一个测试配置对应文件夹
117
+ for root, dirs, files in os.walk(os.path.join(entry, sub_entry)):
118
+ #g 遍历不同长度结果
119
+ for file in files:
120
+ if "metrics" not in file:
121
+ cot_answer_path = file
122
+ cot_answer_path = os.path.join(root, cot_answer_path)
123
+ #G 找到所有存储回答的jsonl文件
124
+ with open(cot_answer_path, "r") as f:
125
+ CoT_metric_single_budget = {}
126
+ budget_length = int(sub_entry)
127
+ CoT_metric_single_budget['budget_length'] = budget_length
128
+ True_list = []
129
+ End_list = []
130
+ for line in f:
131
+ data = json.loads(line)
132
+ if data['score'][0] == False:
133
+ True_list.append(0)
134
+ else:
135
+ True_list.append(1)
136
+
137
+ Thought_END, START, END = get_final_answer_status(data['code'][0])
138
+ End_list.append(Thought_END)
139
+ #G 获取每个回答的最终状态
140
+
141
+ ET_ratio, EF_ratio, OT_ratio, acc = calculate_ratios(End_list, True_list)
142
+
143
+ CoT_metric_single_budget['ET_ratio'] = ET_ratio
144
+ CoT_metric_single_budget['EF_ratio'] = EF_ratio
145
+ CoT_metric_single_budget['OT_ratio'] = OT_ratio
146
+ CoT_metric_single_budget['acc'] = acc
147
+
148
+ CoT_metric_one_setting.append(CoT_metric_single_budget)
149
+ CoT_metric_one_setting.sort(key=lambda x: x['budget_length'])
150
+ fig, axs = plt.subplots(2, 2, figsize=(15, 10))
151
+
152
+ # 定义指标名称和对应的索引
153
+ metrics = ['ET_ratio', 'EF_ratio', 'OT_ratio', 'acc']
154
+ titles = ['ET Ratio', 'EF Ratio', 'OT Ratio', 'Accuracy']
155
+ colors = ['blue', 'green', 'red', 'purple']
156
+ main_title = setting_name
157
+ for i, metric in enumerate(metrics):
158
+ ax = axs[i // 2, i % 2]
159
+ budget_lengths = [data['budget_length'] for data in CoT_metric_one_setting]
160
+ metric_values = [data[metric] for data in CoT_metric_one_setting]
161
+ ax.plot(budget_lengths, metric_values, marker='o', color=colors[i], linewidth=2)
162
+ ax.set_title(titles[i])
163
+ ax.set_xlabel('Budget Length')
164
+ ax.set_ylabel(metric)
165
+ ax.grid(True)
166
+ fig.suptitle(main_title, fontsize=16, y=1)
167
+
168
+ plt.tight_layout()
169
+ pic_name = os.path.join(entry, "metric.png")
170
+ plt.savefig(os.path.join(entry, pic_name), dpi=300)
171
+ print(f"Saved figure as {pic_name}")
172
+ plt.close()
Chain_Of_Thought_Metric/tools.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def is_balanced(s: str) -> bool:
2
+ """验证大括号是否成对且正确嵌套"""
3
+ stack = 0
4
+ for char in s:
5
+ if char == "{":
6
+ stack += 1
7
+ elif char == "}":
8
+ stack -= 1
9
+ if stack < 0:
10
+ return False
11
+ return stack == 0
12
+
13
+
14
+ def find_sequence(array, sequence):
15
+ sequence_length = len(sequence)
16
+ array_length = len(array)
17
+ start_positions = []
18
+
19
+ for i in range(array_length - sequence_length + 1):
20
+ if array[i:i+sequence_length] == sequence:
21
+ start_positions.append(i)
22
+
23
+ return start_positions
24
+
25
+
26
+ def get_final_answer_status(anwser):
27
+ find_string = "**Final Answer**\\boxed"
28
+ sequence = [334, 19357, 21806, 334, 59, 79075]
29
+
30
+ Thought_END = 0
31
+ START = 0
32
+ END = 0
33
+ if not find_string in anwser:
34
+ return Thought_END, START, END
35
+
36
+ else:
37
+ start_idx = anwser.find('**Final Answer**\\boxed{')
38
+ stack = 1
39
+ end_idx = start_idx + len('**Final Answer**\\boxed{')
40
+ while end_idx < len(anwser) and stack > 0:
41
+ if anwser[end_idx] == "{":
42
+ stack += 1
43
+ elif anwser[end_idx] == "}":
44
+ stack -= 1
45
+ end_idx += 1
46
+ if stack == 0 and is_balanced(anwser[start_idx:end_idx]):
47
+ Thought_END = 1
48
+ # tokenized_answer = tokenizer(anwser)['input_ids']
49
+ # #G 找出结束时的token位置
50
+ # start_positions = find_sequence(tokenized_answer, sequence)
51
+
52
+ else:
53
+ Thought_END = 0
54
+
55
+ return Thought_END, START, END
56
+
57
+ def calculate_ratios(thinking_ended, answer_correct):
58
+ # 初始化计数器
59
+ TP_count = 0
60
+ total_count = len(thinking_ended)
61
+ thinking_ended_count = 0
62
+ answer_correct_count = 0
63
+
64
+ # 遍历列表
65
+ for i in range(total_count):
66
+ if thinking_ended[i] == 1 and answer_correct[i] == 1:
67
+ ET_count += 1
68
+ if thinking_ended[i] == 1 and answer_correct[i] == 0:
69
+ EF_count += 1
70
+ if answer_correct[i] == 0 and answer_correct[i] == 1:
71
+ OT_count += 1
72
+
73
+ # 计算比值
74
+ ET_ratio = ET_count / total_count if total_count > 0 else 0
75
+ EF_ratio = TP_count / total_count if total_count > 0 else 0
76
+ OT_ratio = OT_count / total_count if total_count > 0 else 0
77
+
78
+ acc = sum(answer_correct) / total_count if total_count > 0 else 0
79
+
80
+ return ET_ratio, EF_ratio, OT_ratio, acc
Following_Budget_Ratio.png ADDED
GPU_hunter.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import subprocess
2
+ import time
3
+ import logging
4
+
5
+
6
+ logger = logging.getLogger()
7
+ log_file_path = "gpu_hunter.log"
8
+ logger.addHandler(logging.FileHandler(log_file_path))
9
+ logging.basicConfig(filename=log_file_path, level=logging.DEBUG, format='%(asctime)s - %(message)s')
10
+ print("start hunting")
11
+ def get_gpu_memory_usage():
12
+ try:
13
+ output = subprocess.check_output(
14
+ ["nvidia-smi", "--query-gpu=memory.used,memory.total",
15
+ "--format=csv,noheader,nounits", "-i", "0,1,2,3"],
16
+ universal_newlines=True
17
+ )
18
+ return output.strip().split('\n')
19
+ except Exception as e:
20
+ print(f"Error getting GPU info: {e}")
21
+ return None
22
+
23
+ def check_low_usage(threshold=10):
24
+ gpu_data = get_gpu_memory_usage()
25
+ if not gpu_data:
26
+ return False
27
+
28
+ for gpu in gpu_data:
29
+ used, total = map(int, gpu.split(', '))
30
+ usage_percent = (used / total) * 100
31
+ if usage_percent >= threshold:
32
+ return False
33
+ return True
34
+
35
+ def main():
36
+ check_interval = 60*10 # 检查间隔(秒)
37
+ command_to_run = "bash /mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation/remaining_eval/TCMv4_Nratio_copy.sh" # 替换为需要执行的命令
38
+
39
+ while True:
40
+ if check_low_usage(threshold=10):
41
+ time.sleep(check_interval)
42
+ if check_low_usage(threshold=10):
43
+ print("All GPUs have memory usage below 10%. Executing command...")
44
+
45
+ subprocess.run('conda deactivate', shell=True)
46
+ subprocess.run('conda activate QMath-wxr', shell=True)
47
+ subprocess.run(command_to_run, shell=True)
48
+
49
+ print("Command executed. Exiting GPU monitoring.")
50
+ break # 退出循环,停止监听
51
+ else:
52
+ print("GPUs are in use. Waiting...")
53
+
54
+ time.sleep(check_interval)
55
+
56
+ if __name__ == "__main__":
57
+ main()
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Zhibin Gou
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Requirements
2
+ You can install the required packages with the following command:
3
+ ```bash
4
+ cd latex2sympy
5
+ pip install -e .
6
+ cd ..
7
+ pip install -r requirements.txt
8
+ pip install vllm==0.5.1 --no-build-isolation
9
+ pip install transformers==4.42.3
10
+ ```
11
+
12
+ ### Evaluation
13
+ You can evaluate Qwen2.5/Qwen2-Math-Instruct series model with the following command:
14
+ ```bash
15
+ # Qwen2.5-Math-Instruct Series
16
+ PROMPT_TYPE="qwen25-math-cot"
17
+ # Qwen2.5-Math-1.5B-Instruct
18
+ export CUDA_VISIBLE_DEVICES="0"
19
+ MODEL_NAME_OR_PATH="Qwen/Qwen2.5-Math-1.5B-Instruct"
20
+ bash sh/eval.sh $PROMPT_TYPE $MODEL_NAME_OR_PATH
21
+
22
+ # Qwen2.5-Math-7B-Instruct
23
+ export CUDA_VISIBLE_DEVICES="0"
24
+ MODEL_NAME_OR_PATH="Qwen/Qwen2.5-Math-7B-Instruct"
25
+ bash sh/eval.sh $PROMPT_TYPE $MODEL_NAME_OR_PATH
26
+
27
+ # Qwen2.5-Math-72B-Instruct
28
+ export CUDA_VISIBLE_DEVICES="0,1,2,3"
29
+ MODEL_NAME_OR_PATH="Qwen/Qwen2.5-Math-72B-Instruct"
30
+ bash sh/eval.sh $PROMPT_TYPE $MODEL_NAME_OR_PATH
31
+
32
+
33
+ # Qwen2-Math-Instruct Series
34
+ PROMPT_TYPE="qwen-boxed"
35
+ # Qwen2-Math-1.5B-Instruct
36
+ export CUDA_VISIBLE_DEVICES="0"
37
+ MODEL_NAME_OR_PATH="Qwen/Qwen2-Math-1.5B-Instruct"
38
+ bash sh/eval.sh $PROMPT_TYPE $MODEL_NAME_OR_PATH
39
+
40
+ # Qwen2-Math-7B-Instruct
41
+ export CUDA_VISIBLE_DEVICES="0"
42
+ MODEL_NAME_OR_PATH="Qwen/Qwen2-Math-7B-Instruct"
43
+ bash sh/eval.sh $PROMPT_TYPE $MODEL_NAME_OR_PATH
44
+
45
+ # Qwen2-Math-72B-Instruct
46
+ export CUDA_VISIBLE_DEVICES="0,1,2,3"
47
+ MODEL_NAME_OR_PATH="Qwen/Qwen2-Math-72B-Instruct"
48
+ bash sh/eval.sh $PROMPT_TYPE $MODEL_NAME_OR_PATH
49
+ ```
50
+
51
+ ## Acknowledgement
52
+ The codebase is adapted from [math-evaluation-harness](https://github.com/ZubinGou/math-evaluation-harness).
api_test.py ADDED
@@ -0,0 +1,448 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import os
3
+ import argparse
4
+ import time
5
+ from datetime import datetime
6
+ from tqdm import tqdm
7
+ from transformers import AutoTokenizer
8
+ import logging
9
+ import json
10
+ from openai import OpenAI
11
+
12
+ from eval_tools import apply_RL_prompt, solve_final_answer
13
+ from evaluate import evaluate
14
+ from utils import set_seed, load_jsonl, save_jsonl, construct_prompt
15
+ from parser import *
16
+ from trajectory import *
17
+ from data_loader import load_data
18
+ from python_executor import PythonExecutor
19
+
20
+ # Initialize OpenAI client
21
+ client = OpenAI(
22
+ base_url='https://api.apikey.vip/v1',
23
+ api_key='sk-SZvcdq0lrEx3uqgYEs2QuxJ5Eft7ANYK5JPEjHSVAOJHGEzV'
24
+ )
25
+
26
+ ## Setup logging
27
+ if not os.path.exists(f'{os.environ["modelname"]}'):
28
+ os.mkdir(f'{os.environ["modelname"]}')
29
+ if not os.path.exists(f'{os.environ["model"]}'):
30
+ os.mkdir(f'{os.environ["model"]}')
31
+
32
+ DATA_NAME = os.environ["DATA_NAME"]
33
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
34
+ datefmt='%Y-%m-%d %H:%M:%S', filename=f'{os.environ["model"]}/{os.environ["mode"]}-{DATA_NAME}.log', filemode='a')
35
+ print(f"logging in {os.environ['model']}/{os.environ['mode']}-{DATA_NAME}.log")
36
+
37
+ logging.info(f"modelname's infor: {os.environ['modelname']}")
38
+ logging.info(f"mode's infor: {os.environ['mode']}")
39
+ logging.info(f"model's infor: {os.environ['model']}")
40
+
41
+ with open('./special_tokens.json') as f:
42
+ special_tokens = json.load(f)
43
+
44
+ bins_tokens = [
45
+ special_tokens[f"{i}"] for i in range(400)
46
+ ]
47
+
48
+ def clean_code(code):
49
+ for bin_token in bins_tokens:
50
+ if bin_token in code:
51
+ code = code.replace(bin_token, "")
52
+ return code
53
+
54
+ def parse_args():
55
+ parser = argparse.ArgumentParser()
56
+ parser.add_argument("--ratio", type=float, default=-1, help="ratio of cot to use for generation")
57
+ parser.add_argument("--data_names", default="math", type=str)
58
+ parser.add_argument("--data_dir", default="./data", type=str)
59
+ parser.add_argument("--model_name_or_path", default="Qwen/QwQ-32B-Preview", type=str)
60
+ parser.add_argument("--output_dir", default="Qwen/QwQ-32B-Preview/math_eval", type=str)
61
+ parser.add_argument("--prompt_type", default="qwen25-math-cot", type=str)
62
+ parser.add_argument("--split", default="test", type=str)
63
+ parser.add_argument("--num_test_sample", default=-1, type=int) # -1 for full data
64
+ parser.add_argument("--seed", default=0, type=int)
65
+ parser.add_argument("--start", default=0, type=int)
66
+ parser.add_argument("--end", default=-1, type=int)
67
+ parser.add_argument("--temperature", default=0, type=float)
68
+ parser.add_argument("--n_sampling", default=1, type=int)
69
+ parser.add_argument("--top_p", default=1, type=float)
70
+ parser.add_argument("--max_tokens_per_call", default=4096, type=int)
71
+ parser.add_argument("--shuffle", action="store_true")
72
+ parser.add_argument("--use_vllm", action="store_true")
73
+ parser.add_argument("--save_outputs", action="store_true")
74
+ parser.add_argument("--overwrite", action="store_true")
75
+ parser.add_argument("--use_safetensors", action="store_true")
76
+ parser.add_argument("--num_shots", type=int, default=0)
77
+ parser.add_argument("--apply_chat_template", action="store_true", help="Apply chat template to prompt.",)
78
+ args = parser.parse_args()
79
+ args.top_p = (1 if args.temperature == 0 else args.top_p)
80
+ return args
81
+
82
+ def set_output_path(args, data_name):
83
+ model_name_list = args.model_name_or_path.split('/')[-1]
84
+ model_name = model_name_list
85
+ for part in model_name_list:
86
+ if 'models' in part:
87
+ model_name = part
88
+
89
+ output_dir = os.path.join(args.output_dir, model_name, args.prompt_type)
90
+ out_file_prefix = f"{args.split}_{args.prompt_type}_{args.num_test_sample}_seed{args.seed}_t{args.temperature}"
91
+ out_file = f"{output_dir}/{data_name}/{out_file_prefix}_s{args.start}_e{args.end}_b{int(args.max_tokens_per_call)}_original.jsonl"
92
+ print(out_file)
93
+ os.makedirs(f"{output_dir}/{data_name}", exist_ok=True)
94
+ return out_file_prefix, output_dir, out_file
95
+
96
+ def prepare_data(data_name, args):
97
+ examples = load_data(data_name, args.split, args.data_dir)
98
+
99
+ if args.num_test_sample > 0:
100
+ examples = examples[: args.num_test_sample]
101
+
102
+ if args.shuffle:
103
+ random.seed(datetime.now().timestamp())
104
+ random.shuffle(examples)
105
+
106
+ examples = examples[args.start : len(examples) if args.end == -1 else args.end]
107
+
108
+ dt_string = datetime.now().strftime("%m-%d_%H-%M")
109
+ model_name = "/".join(args.model_name_or_path.split("/")[-2:])
110
+
111
+ out_file_prefix, output_dir, out_file = set_output_path(args, data_name)
112
+
113
+ processed_samples = []
114
+ if not args.overwrite:
115
+ processed_files = [
116
+ f
117
+ for f in os.listdir(f"{output_dir}/{data_name}/")
118
+ if f.endswith(".jsonl") and f.startswith(out_file_prefix)
119
+ ]
120
+ for f in processed_files:
121
+ processed_samples.extend(
122
+ list(load_jsonl(f"{output_dir}/{data_name}/{f}"))
123
+ )
124
+
125
+ processed_samples = {sample["idx"]: sample for sample in processed_samples}
126
+ processed_idxs = list(processed_samples.keys())
127
+ processed_samples = list(processed_samples.values())
128
+ examples = [example for example in examples if example["idx"] not in processed_idxs]
129
+ return examples, processed_samples, out_file
130
+
131
+ def is_multi_choice(answer):
132
+ for c in answer:
133
+ if c not in ["A", "B", "C", "D", "E"]:
134
+ return False
135
+ return True
136
+
137
+ def get_api_response(prompt, max_tokens=4096, temperature=0.5):
138
+ try:
139
+ completion = client.chat.completions.create(
140
+ messages=[
141
+ {
142
+ "role": "user",
143
+ "content": prompt,
144
+ }
145
+ ],
146
+ model="o1-mini",
147
+ timeout=200,
148
+ temperature=temperature,
149
+ max_tokens=max_tokens,
150
+ )
151
+ return completion.choices[0].message.content
152
+ except Exception as e:
153
+ print(f"Error in API call: {e}")
154
+ return ""
155
+
156
+ def main(llm, tokenizer, data_name, args):
157
+ examples, processed_samples, out_file = prepare_data(data_name, args)
158
+ print(examples[0])
159
+ print("\n" + "-" * 50)
160
+ print("data:", data_name, ", remain samples:", len(examples))
161
+ if len(examples) > 0:
162
+ print(examples[0])
163
+
164
+ # init python executor
165
+ if "pal" in args.prompt_type:
166
+ executor = PythonExecutor(get_answer_expr="solution()")
167
+ else:
168
+ executor = PythonExecutor(get_answer_from_stdout=True)
169
+
170
+ # load done samples
171
+ if args.ratio > 0:
172
+ done_samples_path = out_file.replace("_r" + str(args.ratio), "")
173
+ done_samples = list(load_jsonl(done_samples_path))
174
+ else:
175
+ done_samples = []
176
+ done_samples = {sample["idx"]: sample for sample in done_samples}
177
+
178
+ samples = []
179
+ print("\nProcessing", len(examples), "examples", "=" * 50)
180
+ for example in tqdm(examples, total=len(examples)):
181
+ idx = example["idx"]
182
+
183
+ # parse question and answer
184
+ example["question"] = parse_question(example, data_name)
185
+ if example["question"] == "":
186
+ continue
187
+ gt_cot, gt_ans = parse_ground_truth(example, data_name)
188
+ example["gt_ans"] = gt_ans
189
+ full_prompt = construct_prompt(example, data_name, args)
190
+
191
+ if args.ratio > 0:
192
+ done_cot = done_samples[idx]["code"][0]
193
+ cut_cot = done_cot[:int(len(done_cot)*args.ratio)]
194
+ full_prompt = full_prompt + cut_cot + "\n\nFinal answer within \\boxed{{}}:\n"
195
+
196
+ if idx == args.start:
197
+ print(full_prompt)
198
+
199
+ sample = {
200
+ "idx": idx,
201
+ "question": example["question"],
202
+ "gt_cot": gt_cot,
203
+ "gt": gt_ans,
204
+ "prompt": full_prompt,
205
+ }
206
+
207
+ # add remain fields
208
+ for key in [
209
+ "level",
210
+ "type",
211
+ "unit",
212
+ "solution_type",
213
+ "choices",
214
+ "solution",
215
+ "ques_type",
216
+ "ans_type",
217
+ "answer_type",
218
+ "dataset",
219
+ "subfield",
220
+ "filed",
221
+ "theorem",
222
+ "answer",
223
+ ]:
224
+ if key in example:
225
+ sample[key] = example[key]
226
+ samples.append(sample)
227
+
228
+ # repeat n times
229
+ input_prompts = [sample["prompt"] for sample in samples for _ in range(args.n_sampling)]
230
+ input_prompts = apply_RL_prompt(input_prompts, args, budget=args.max_tokens_per_call)
231
+
232
+ if args.apply_chat_template:
233
+ tokenizer = AutoTokenizer.from_pretrained(
234
+ args.model_name_or_path, trust_remote_code=True, max_length=16000,
235
+ )
236
+ input_prompts = [
237
+ tokenizer.apply_chat_template(
238
+ [{"role": "user", "content": prompt.strip()}],
239
+ tokenize=False,
240
+ add_generation_prompt=True,
241
+ )
242
+ for prompt in input_prompts
243
+ ]
244
+
245
+ remain_prompts = input_prompts
246
+ remain_prompts = [(i, prompt) for i, prompt in enumerate(remain_prompts)]
247
+ end_prompts = []
248
+
249
+ max_func_call = 1 if args.prompt_type in ["cot", "pal", "qwen25-math-cot"] else 4
250
+
251
+ stop_words = ["</s>", "<|im_end|>", "<|endoftext|>"]
252
+
253
+ if args.prompt_type in ["cot"]:
254
+ stop_words.append("\n\nQuestion:")
255
+ if args.prompt_type in ["pal", "tool-integrated", "jiuzhang_tora"]:
256
+ stop_words.extend(["\n\n---", "```output"])
257
+ elif args.prompt_type in ["wizard_zs", "platypus_fs"]:
258
+ stop_words.extend(["Instruction", "Response"])
259
+ elif "jiuzhang" in args.prompt_type:
260
+ stop_words.append("\n\n## Question")
261
+ elif "numina" in args.prompt_type:
262
+ stop_words.append("\n### Problem")
263
+ elif "pure" in args.prompt_type:
264
+ stop_words.append("\n\n\n")
265
+
266
+ # start inference
267
+ start_time = time.time()
268
+ print(f"start_time: {start_time}")
269
+ for epoch in range(max_func_call):
270
+ print("-" * 20, "Epoch", epoch)
271
+ current_prompts = remain_prompts
272
+ if len(current_prompts) == 0:
273
+ break
274
+
275
+ prompts = [item[1] for item in current_prompts]
276
+
277
+ # Call API for each prompt
278
+ outputs = []
279
+ for prompt in tqdm(prompts, desc="Calling API"):
280
+ response = get_api_response(prompt, max_tokens=args.max_tokens_per_call, temperature=args.temperature)
281
+ outputs.append(response)
282
+
283
+ print('stage one finished!!!\n' * 20)
284
+ print(outputs[:3])
285
+
286
+ if os.environ['stage'] == "2":
287
+ print("stage 2")
288
+ modified_outputs = []
289
+ for output in outputs:
290
+ if "" in output:
291
+ start_index = output.index("")
292
+ output = output[:start_index]
293
+ modified_output = output + "\n</think>\n\n**Final Answer**\\boxed"
294
+ modified_outputs.append(modified_output)
295
+
296
+ # Call API again for stage 2
297
+ stage2_outputs = []
298
+ for prompt in tqdm(modified_outputs, desc="Stage 2 API calls"):
299
+ response = get_api_response(prompt, max_tokens=20, temperature=args.temperature)
300
+ stage2_outputs.append(response)
301
+
302
+ outputs = stage2_outputs
303
+
304
+ assert len(outputs) == len(current_prompts)
305
+
306
+ # process all outputs
307
+ remain_prompts = []
308
+ remain_codes = []
309
+ for (i, query), output in zip(current_prompts, outputs):
310
+ output = output.rstrip()
311
+ query += output
312
+ if args.prompt_type == "pal":
313
+ remain_prompts.append((i, query))
314
+ if "```python" in output:
315
+ output = extract_program(query)
316
+ remain_codes.append(output)
317
+ elif args.prompt_type == "cot":
318
+ end_prompts.append((i, query))
319
+ elif "boxed" not in output and output.endswith("```"):
320
+ program = extract_program(query)
321
+ remain_prompts.append((i, query))
322
+ remain_codes.append(program)
323
+ else:
324
+ end_prompts.append((i, query))
325
+
326
+ # execute the remain prompts
327
+ remain_results = executor.batch_apply(remain_codes)
328
+ for k in range(len(remain_prompts)):
329
+ i, query = remain_prompts[k]
330
+ res, report = remain_results[k]
331
+ exec_result = res if res else report
332
+ if "pal" in args.prompt_type:
333
+ exec_result = "\\boxed{" + exec_result + "}"
334
+ exec_result = f"\n```output\n{exec_result}\n```\n"
335
+ query += exec_result
336
+ if epoch == max_func_call - 1:
337
+ query += "\nReach max function call limit."
338
+ remain_prompts[k] = (i, query)
339
+
340
+ # unsolved samples
341
+ print("Unsolved samples:", len(remain_prompts))
342
+ end_prompts.extend(remain_prompts)
343
+ end_prompts = sorted(end_prompts, key=lambda x: x[0])
344
+
345
+ # remove input_prompt from end_prompt
346
+ codes = []
347
+ assert len(input_prompts) == len(end_prompts)
348
+ for i in range(len(input_prompts)):
349
+ _, end_prompt = end_prompts[i]
350
+ code = end_prompt.split(input_prompts[i])[-1].strip()
351
+ for stop_word in stop_words:
352
+ if stop_word in code:
353
+ code = code.split(stop_word)[0].strip()
354
+ if args.prompt_type == "deepseek3":
355
+ if '```' in code:
356
+ code = code.split("```")[1]
357
+ codes.append(code)
358
+
359
+ results = [
360
+ run_execute(executor, clean_code(code), args.prompt_type, data_name) for code in codes
361
+ ]
362
+ time_use = time.time() - start_time
363
+
364
+ # put results back to examples
365
+ all_samples = []
366
+ for i, sample in enumerate(samples):
367
+ code = codes[i * args.n_sampling : (i + 1) * args.n_sampling]
368
+ result = results[i * args.n_sampling : (i + 1) * args.n_sampling]
369
+ preds = [item[0] for item in result]
370
+ reports = [item[1] for item in result]
371
+ for j in range(len(preds)):
372
+ if sample["gt"] in ["A", "B", "C", "D", "E"] and preds[j] not in [
373
+ "A",
374
+ "B",
375
+ "C",
376
+ "D",
377
+ "E",
378
+ ]:
379
+ preds[j] = choice_answer_clean(code[j])
380
+ elif is_multi_choice(sample["gt"]) and not is_multi_choice(preds[j]):
381
+ preds[j] = "".join(
382
+ [c for c in preds[j] if c in ["A", "B", "C", "D", "E"]]
383
+ )
384
+
385
+ sample.update({"code": code, "pred": preds, "report": reports})
386
+ all_samples.append(sample)
387
+
388
+ # add processed samples
389
+ all_samples.extend(processed_samples)
390
+ all_samples, result_json = evaluate(
391
+ samples=all_samples,
392
+ data_name=data_name,
393
+ prompt_type=args.prompt_type,
394
+ execute=True,
395
+ )
396
+
397
+ # save outputs
398
+ if len(processed_samples) < len(all_samples) and args.save_outputs:
399
+ save_jsonl(all_samples, out_file)
400
+
401
+ result_json["time_use_in_second"] = time_use
402
+ result_json["time_use_in_minite"] = (
403
+ f"{int(time_use // 60)}:{int(time_use % 60):02d}"
404
+ )
405
+
406
+ with open(
407
+ out_file.replace(".jsonl", "_metrics.json"), "w"
408
+ ) as f:
409
+ json.dump(result_json, f, indent=4)
410
+ return result_json
411
+
412
+ def setup(args):
413
+ tokenizer = None
414
+ if args.apply_chat_template:
415
+ tokenizer = AutoTokenizer.from_pretrained(
416
+ args.model_name_or_path, trust_remote_code=True, max_length=16000,
417
+ )
418
+
419
+ # infer & eval
420
+ data_list = args.data_names.split(",")
421
+ results = []
422
+ for data_name in data_list:
423
+ results.append(main(None, tokenizer, data_name, args))
424
+
425
+ # add "avg" result
426
+ data_list.append("avg")
427
+ results.append(
428
+ {
429
+ "acc": sum([result["acc"] for result in results]) / len(results),
430
+ }
431
+ )
432
+
433
+ # print all results
434
+ pad = max([len(data_name) for data_name in data_list])
435
+ print("\t".join(data_name.ljust(pad, " ") for data_name in data_list))
436
+ print("\t".join([f"{result['acc']:.1f}".ljust(pad, " ") for result in results]))
437
+
438
+ logging.info("\t".join(data_name.ljust(pad, " ") for data_name in data_list))
439
+ logging.info(f"os.environ['PE_MODE'] = {os.environ['PE_MODE']}")
440
+ logging.info(f"path = {args.model_name_or_path}")
441
+ logging.info(f"tip = {os.environ['tip']}")
442
+ logging.info(f"BUDGET = {os.environ['BUDGET']}")
443
+ logging.info("\t".join([f"{result['acc']:.1f}".ljust(pad, " ") for result in results]))
444
+
445
+ if __name__ == "__main__":
446
+ args = parse_args()
447
+ set_seed(args.seed)
448
+ setup(args)
copy_backup.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import shutil
3
+
4
+ def copy_folder(src, dst):
5
+ """
6
+ 复制文件夹,忽略以字母t开头的子文件夹
7
+ :param src: 源文件夹路径
8
+ :param dst: 目标文件夹路径
9
+ """
10
+ # 确保目标文件夹存在
11
+ if not os.path.exists(dst):
12
+ os.makedirs(dst)
13
+
14
+ # 遍历源文件夹
15
+ for item in os.listdir(src):
16
+ src_item = os.path.join(src, item)
17
+ dst_item = os.path.join(dst, item)
18
+
19
+ # 如果是文件,直接复制
20
+ if os.path.isfile(src_item):
21
+ shutil.copy2(src_item, dst_item)
22
+ # 如果是文件夹
23
+ elif os.path.isdir(src_item):
24
+ # 如果文件夹名以t开头,跳过
25
+ if item.lower().startswith('model'):
26
+ print(f"Skipping folder: {item}")
27
+ continue
28
+ # 否则递归复制文件夹
29
+ copy_folder(src_item, dst_item)
30
+
31
+ # 示例用法
32
+ source_folder = "/mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation" # 源文件夹路径
33
+ destination_folder = "/mnt/lyc/wuxinrui/BudgetThinker/evaluation" # 目标文件夹路径
34
+
35
+ copy_folder(source_folder, destination_folder)
36
+ print("Folder copied successfully.")
data/aime24/aime24.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:233fada048d48294f7d7a78ecec38563eaea206ae9eb92c35684c7aac469bb47
3
+ size 10230
data/amc23/amc23.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cb2c49887d2a73ffb5b8e37f5352a8deca779f5a2308bba089a317338fd10545
3
+ size 9919
data/carp_en/demo.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {"content": "If $3 a ^ { m + 2 } b$ and $\\frac { 1 } { 2 } ab ^ { n - 1 }$ are similar terms, then $m + n$ is equal to.", "answer": "1", "steps": "$3 a ^ { m + 2 } b$ and $\\frac { 1 } { 2 } ab ^ { n - 1 }$ are like terms. We can obtain $m + 2 = 1$ and $n - 1 = 1$. Solving for $m$ and $n$, we get $m = - 1$ and $n = 2$. Therefore, $m + n = - 1 + 2 = 1$.", "expr_cands": ["3 a ^ { m + 2 } b", "a", "m", "b", "\\frac { 1 } { 2 } ab ^ { n - 1 }", "n", "m + n", "m + 2 = 1", "m = - 1", "n - 1 = 1", "n = 2", "1"], "exprs": ["m + 2 = 1", "n - 1 = 1", "m = - 1", "n = 2", "1"], "edges": {"directed": true, "multigraph": false, "graph": {}, "nodes": [{"id": "3 a ^ { m + 2 } b"}, {"id": "m + 2 = 1"}, {"id": "\\frac { 1 } { 2 } ab ^ { n - 1 }"}, {"id": "$3 a ^ { m + 2 } b$ 与 $\\frac { 1 } { 2 } ab ^ { n - 1 }$ 是同类项"}, {"id": "n - 1 = 1"}, {"id": "m = - 1"}, {"id": "n = 2"}, {"id": "m + n"}, {"id": "1"}], "links": [{"rel": "被描述", "source": "3 a ^ { m + 2 } b", "target": "m + 2 = 1"}, {"rel": "被描述", "source": "3 a ^ { m + 2 } b", "target": "n - 1 = 1"}, {"rel": "等式方程求解", "source": "m + 2 = 1", "target": "m = - 1"}, {"rel": "被描述", "source": "\\frac { 1 } { 2 } ab ^ { n - 1 }", "target": "m + 2 = 1"}, {"rel": "被描述", "source": "\\frac { 1 } { 2 } ab ^ { n - 1 }", "target": "n - 1 = 1"}, {"rel": "限制性描述", "source": "$3 a ^ { m + 2 } b$ 与 $\\frac { 1 } { 2 } ab ^ { n - 1 }$ 是同类项", "target": "m + 2 = 1"}, {"rel": "限制性描述", "source": "$3 a ^ { m + 2 } b$ 与 $\\frac { 1 } { 2 } ab ^ { n - 1 }$ 是同类项", "target": "n - 1 = 1"}, {"rel": "等式方程求解", "source": "n - 1 = 1", "target": "n = 2"}, {"rel": "代入", "source": "m = - 1", "target": "1"}, {"rel": "代入", "source": "n = 2", "target": "1"}, {"rel": "被代入", "source": "m + n", "target": "1"}]}}
2
+ {"content": "The solution to the equation $y - \\frac { y - 1 } { 2 } = - \\frac { y + 2 } { 5 }$ is ____ ?", "answer": "y = - \\frac { 9 } { 7 }", "steps": "To eliminate the denominator, we have $10 y - 5 ( y - 1 ) = - 2 ( y + 2 )$. Expanding the brackets gives $10 y - 5 y + 5 = - 2 y - 4$. Rearranging terms gives $10 y - 5 y + 2 y = - 4 - 5$, which simplifies to $7 y = - 9$. Dividing both sides by 7 gives $y = - \\frac { 9 } { 7 }$.", "expr_cands": ["y - \\frac { y - 1 } { 2 } = - \\frac { y + 2 } { 5 }", "y", "10 y - 5 ( y - 1 ) = - 2 ( y + 2 )", "y = - \\frac { 9 } { 7 }", "10 y - 5 y + 5 = - 2 y - 4", "10 y - 5 y + 2 y = - 4 - 5", "7 y = - 9", "1"], "exprs": ["y = - \\frac { 9 } { 7 }"], "edges": {"directed": true, "multigraph": false, "graph": {}, "nodes": [{"id": "y - \\frac { y - 1 } { 2 } = - \\frac { y + 2 } { 5 }"}, {"id": "y = - \\frac { 9 } { 7 }"}], "links": [{"rel": "等式方程求解", "source": "y - \\frac { y - 1 } { 2 } = - \\frac { y + 2 } { 5 }", "target": "y = - \\frac { 9 } { 7 }"}]}}
3
+ {"content": "If $( m + 4 ) ^ 2 + | n - 3 | = 0$, then $\\frac { 1 } { 2 } m - n$ = ____?", "answer": "- 5", "steps": "$\\because ( m + 4 ) ^ 2 + | n - 3 | = 0$, $\\therefore m + 4 = 0$, $n - 3 = 0$, which means $m = - 4$, $n = 3$. Then the original expression equals $- 2 - 3 = - 5$.", "expr_cands": ["( m + 4 ) ^ { 2 } + | n - 3 | = 0", "m", "n", "\\frac { 1 } { 2 } m - n", "m + 4 = 0", "m = - 4", "n - 3 = 0", "n = 3", "- 2 - 3", "- 5"], "content_formula": [[["(", "m", "+", "4", ")", "^", "{", "2", "}", "+", "|", "n", "-", "3", "|", "=", "0"], ["\\frac", "{", "1", "}", "{", "2", "}", "m", "-", "n"]], [[1, 18], [20, 30]]], "steps_formula": [[["(", "m", "+", "4", ")", "^", "{", "2", "}", "+", "|", "n", "-", "3", "|", "=", "0"], ["m", "+", "4", "=", "0"], ["n", "-", "3", "=", "0"], ["m", "=", "-", "4"], ["n", "=", "3"], ["-", "2", "-", "3", "=", "-", "5"]], [[1, 18], [20, 25], [26, 31], [33, 37], [38, 41], [45, 52]]], "exprs": ["m + 4 = 0", "n - 3 = 0", "m = - 4", "n = 3", "- 5"], "edges": {"directed": true, "multigraph": false, "graph": {}, "nodes": [{"id": "( m + 4 ) ^ { 2 } + | n - 3 | = 0"}, {"id": "m + 4 = 0"}, {"id": "绝对值恒大于等于0"}, {"id": "n - 3 = 0"}, {"id": "多项式偶次方项恒大于等于0"}, {"id": "m = - 4"}, {"id": "n = 3"}, {"id": "\\frac { 1 } { 2 } m - n"}, {"id": "- 5"}], "links": [{"rel": "被描述", "source": "( m + 4 ) ^ { 2 } + | n - 3 | = 0", "target": "m + 4 = 0"}, {"rel": "被描述", "source": "( m + 4 ) ^ { 2 } + | n - 3 | = 0", "target": "n - 3 = 0"}, {"rel": "等式方程求解", "source": "m + 4 = 0", "target": "m = - 4"}, {"rel": "属性描述", "source": "绝对值恒大于等于0", "target": "m + 4 = 0"}, {"rel": "等式方程求解", "source": "n - 3 = 0", "target": "n = 3"}, {"rel": "属性描述", "source": "多项式偶次方项恒大于等于0", "target": "n - 3 = 0"}, {"rel": "代入", "source": "m = - 4", "target": "- 5"}, {"rel": "代入", "source": "n = 3", "target": "- 5"}, {"rel": "被代入", "source": "\\frac { 1 } { 2 } m - n", "target": "- 5"}]}}
4
+ {"content": "Given a quadratic equation in one variable $x$, $x ^ 2 + x + m = 0$, with one root being $x = 1$, what is the other root of this equation?", "answer": "- 2", "steps": "Suppose the quadratic equation in one variable about $x$ is $x ^ 2 + x + m = 0$, and $\\alpha$ is another real root of the equation. Since one real root of the quadratic equation in one variable about $x$ is $1$, we have $\\alpha + 1 = - 1$. Therefore, $\\alpha = - 2$.", "expr_cands": ["x", "x ^ { 2 } + x + m = 0", "m", "x = 1", "1", "\\alpha + 1 = - 1", "alpha = - 2", "\\alpha", "\\alpha = - 2"], "exprs": ["\\alpha + 1 = - 1", "\\alpha = - 2"], "edges": {"directed": true, "multigraph": false, "graph": {}, "nodes": [{"id": "x ^ { 2 } + x + m = 0"}, {"id": "\\alpha + 1 = - 1"}, {"id": "x = 1"}, {"id": "关于 $x$ 的一元二次方程 $x ^ { 2 } + x + m = 0$ 的一个根是 $x = 1$"}, {"id": "设关于 $x$ 的一元二次方程 $x ^ { 2 } + x + m = 0$ 的另一个实数根是 \\alpha"}, {"id": "一元二次方程根与系数关系,两根之和"}, {"id": "\\alpha = - 2"}], "links": [{"rel": "被描述", "source": "x ^ { 2 } + x + m = 0", "target": "\\alpha + 1 = - 1"}, {"rel": "等式方程求解", "source": "\\alpha + 1 = - 1", "target": "\\alpha = - 2"}, {"rel": "被描述", "source": "x = 1", "target": "\\alpha + 1 = - 1"}, {"rel": "限制性描述", "source": "关于 $x$ 的一元二次方程 $x ^ { 2 } + x + m = 0$ 的一个根是 $x = 1$", "target": "\\alpha + 1 = - 1"}, {"rel": "假设描述", "source": "设关于 $x$ 的一元二次方程 $x ^ { 2 } + x + m = 0$ 的另一个实数根是 \\alpha", "target": "\\alpha + 1 = - 1"}, {"rel": "属性描述", "source": "一元二次方程根与系数关系,两根之和", "target": "\\alpha + 1 = - 1"}]}}
5
+ {"content": "The parabola $y = - 5 { x } ^ 2 + 1$ is translated $2$ units upward and $1$ unit to the left, resulting in the parabola _____.", "answer": "y = - 5 ( x + 1 ) ^ { 2 } + 3", "steps": "The parabola $y = - 5 { x } ^ 2 + 1$ is first shifted upward by 2 units, resulting in $y = - 5 { x } ^ 2 + 3$. Then it is shifted left by 1 unit, resulting in $y = - 5 {( x + 1 )} ^ 2 + 3$.", "expr_cands": ["y = - 5 { x } ^ { 2 } + 1", "y", "x", "2", "1", "y = - 5 { x } ^ { 2 } + 3", "1 - 5 x ^ { 2 } = - 5 { x } ^ { 2 } + 3", "y = - 5 { ( x + 1 ) } ^ { 2 } + 3", "3 - 5 x ^ { 2 } = - 5 { ( x + 1 ) } ^ { 2 } + 3", "3 - 5 x ^ { 2 }", "y = - 5 ( x + 1 ) ^ { 2 } + 3"], "exprs": ["y = - 5 { ( x + 1 ) } ^ { 2 } + 3"], "edges": {"directed": true, "multigraph": false, "graph": {}, "nodes": [{"id": "2"}, {"id": "y = - 5 { ( x + 1 ) } ^ { 2 } + 3"}, {"id": "y = - 5 { x } ^ { 2 } + 1"}, {"id": "1"}, {"id": "将抛物线 $y = - 5 { x } ^ { 2 } + 1$ 向上平移 $2$ 个单位长度"}, {"id": "再向左平移 $1$ 个单位长度"}], "links": [{"rel": "被描述", "source": "2", "target": "y = - 5 { ( x + 1 ) } ^ { 2 } + 3"}, {"rel": "被描述", "source": "y = - 5 { x } ^ { 2 } + 1", "target": "y = - 5 { ( x + 1 ) } ^ { 2 } + 3"}, {"rel": "被描述", "source": "1", "target": "y = - 5 { ( x + 1 ) } ^ { 2 } + 3"}, {"rel": "限制性描述", "source": "将抛物线 $y = - 5 { x } ^ { 2 } + 1$ 向上平移 $2$ 个单位长度", "target": "y = - 5 { ( x + 1 ) } ^ { 2 } + 3"}, {"rel": "限制性描述", "source": "再向左平移 $1$ 个单位长度", "target": "y = - 5 { ( x + 1 ) } ^ { 2 } + 3"}]}}
6
+ {"content": "If the radical $\\sqrt { x - 8 }$ is defined, then the range of real numbers for $x$ is ____ ?", "answer": "x \\ge 8", "steps": "Since the radical $\\sqrt { x - 8 }$ is defined, therefore $x - 8 \\ge 0$, which implies $x \\ge 8$.", "expr_cands": ["\\sqrt { x - 8 }", "x", "x - 8 \\ge 0", "8 \\le x", "x \\ge 8"], "exprs": ["x - 8 \\ge 0", "x \\ge 8"], "edges": {"directed": true, "multigraph": false, "graph": {}, "nodes": [{"id": "\\sqrt { x - 8 }"}, {"id": "x - 8 \\ge 0"}, {"id": "根式 $\\sqrt { x - 8 }$ 有意义"}, {"id": "二次根式有意义,则根式恒大于等于0"}, {"id": "x \\ge 8"}], "links": [{"rel": "被描述", "source": "\\sqrt { x - 8 }", "target": "x - 8 \\ge 0"}, {"rel": "不等式方程求解", "source": "x - 8 \\ge 0", "target": "x \\ge 8"}, {"rel": "限制性描述", "source": "根式 $\\sqrt { x - 8 }$ 有意义", "target": "x - 8 \\ge 0"}, {"rel": "属性描述", "source": "二次根式有意义,则根式恒大于等于0", "target": "x - 8 \\ge 0"}]}}
7
+ {"content": "If $a ^ { m } \\times a ^ { 2 } = a ^ { 7 }$, then the value of $m$ is ____?", "answer": "5", "steps": "According to the multiplication rule of powers with the same base: when multiplying powers with the same base, keep the base the same and add the exponents. We have $m + 2 = 7$, so solving for $m$ gives $m = 5$.", "expr_cands": ["a ^ { m } \\times a ^ { 2 } = a ^ { 7 }", "a", "m", "m + 2 = 7", "m = 5"], "exprs": ["m + 2 = 7", "m = 5"], "edges": {"directed": true, "multigraph": false, "graph": {}, "nodes": [{"id": "a ^ { m } \\times a ^ { 2 } = a ^ { 7 }"}, {"id": "m + 2 = 7"}, {"id": "m = 5"}], "links": [{"rel": "同取对数", "source": "a ^ { m } \\times a ^ { 2 } = a ^ { 7 }", "target": "m + 2 = 7"}, {"rel": "等式方程求解", "source": "m + 2 = 7", "target": "m = 5"}]}}
8
+ {"content": "If line segment $a$ and $b$ satisfy $\\frac { a } { b } = \\frac { 5 } { 2 }$, then the value of $\\frac { a - b } { b }$ is ____?", "answer": "\\frac { 3 } { 2 }", "steps": "$\\because \\frac { a } { b } = \\frac { 5 } { 2 }$, $\\therefore$ we can assume $a = 5 k$, then $b = 2 k$, $\\therefore \\frac { a - b } { b } = \\frac { 5 k - 2 k } { 2 k } = \\frac { 3 } { 2 }$.", "expr_cands": ["a", "b", "\\frac { a } { b } = \\frac { 5 } { 2 }", "\\frac { a - b } { b }", "a = 5 k", "k", "b = 2 k", "\\frac { 3 } { 2 }"], "exprs": ["a = 5 k", "b = 2 k", "\\frac { 3 } { 2 }"], "edges": {"directed": true, "multigraph": false, "graph": {}, "nodes": [{"id": "\\frac { a } { b } = \\frac { 5 } { 2 }"}, {"id": "a = 5 k"}, {"id": "可设 $a = 5 k$"}, {"id": "线段 $a$ , $b$ 满足 $\\frac { a } { b } = \\frac { 5 } { 2 }$"}, {"id": "b = 2 k"}, {"id": "设b=2k"}, {"id": "\\frac { a - b } { b }"}, {"id": "\\frac { 3 } { 2 }"}], "links": [{"rel": "被描述", "source": "\\frac { a } { b } = \\frac { 5 } { 2 }", "target": "a = 5 k"}, {"rel": "被描述", "source": "\\frac { a } { b } = \\frac { 5 } { 2 }", "target": "b = 2 k"}, {"rel": "代入", "source": "a = 5 k", "target": "\\frac { 3 } { 2 }"}, {"rel": "假设描述", "source": "可设 $a = 5 k$", "target": "a = 5 k"}, {"rel": "限制性描述", "source": "线段 $a$ , $b$ 满足 $\\frac { a } { b } = \\frac { 5 } { 2 }$", "target": "a = 5 k"}, {"rel": "限制性描述", "source": "线段 $a$ , $b$ 满足 $\\frac { a } { b } = \\frac { 5 } { 2 }$", "target": "b = 2 k"}, {"rel": "代入", "source": "b = 2 k", "target": "\\frac { 3 } { 2 }"}, {"rel": "假设描述", "source": "设b=2k", "target": "b = 2 k"}, {"rel": "被代入", "source": "\\frac { a - b } { b }", "target": "\\frac { 3 } { 2 }"}]}}
data/math500/math500_RL.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1686bb35a32b22c862b4c81c4fe8b6923049f2e7c5cb71f5c0c9a1c584258f4b
3
+ size 64102
data/math500_answer_prompt/get_answer_prompt.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+
4
+
5
+ def get_answer_prompt():
6
+ answer_prompt_data = []
7
+ with open("/mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation/data/math500/test.jsonl", "r") as f:
8
+ for line in f:
9
+ data = json.loads(line)
10
+ answer = data["answer"]
11
+ problem = data["problem"]
12
+
13
+ answer_prompt = f"The answer to this question is {answer}. Based on the answer and the constraints of the thought chain length, you should deduce the most logical reasoning process. Note: During the thought process, you should pretend not to have seen the answer, but you must rationally infer the correct answer mentioned earlier based on the content of the thought chain."
14
+
15
+ data['problem'] = problem+answer_prompt
16
+ answer_prompt_data.append(data)
17
+
18
+ with open("/mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation/data/math500_answer_prompt/test.jsonl", "w") as f:
19
+ for data in answer_prompt_data:
20
+ f.write(json.dumps(data, ensure_ascii=False) + "\n")
21
+
22
+ if __name__ == "__main__":
23
+ get_answer_prompt()
24
+
data/minerva_math/README.md ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ MIT OpenCourseWare:
2
+ - Solving Quantitative Reasoning Problems with Language Models. https://openreview.net/forum?id=IFXTZERXdM7
data/olympiadbench/test.json ADDED
The diff for this file is too large to render. See raw diff
 
data/trans_parquet.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import json
3
+
4
+
5
+ def trans_parquet(jsonl_path, save_path):
6
+ with open(jsonl_path, 'r') as f:
7
+ data = [json.loads(line) for line in f]
8
+
9
+ RL_data_list = []
10
+ for item in data:
11
+ QA = {
12
+ "problem": "Return your final response within \\boxed{}. " + item['problem'],
13
+ "answer": item['answer'],
14
+ }
15
+ RL_data_list.append(QA)
16
+ RL_data = pd.DataFrame(RL_data_list)
17
+ RL_data.to_parquet(save_path, index=False)
18
+
19
+
20
+ def read_parquet(save_path):
21
+ data = pd.read_parquet(save_path)
22
+ print(data.head())
23
+ return data
24
+
25
+ if __name__ == "__main__":
26
+ trans_parquet("/mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation/data/amc23/test.jsonl", "/mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation/data/amc23/amc23.parquet")
27
+
28
+ read_parquet("/mnt/lyc/wuxinrui/Qwen2.5-Math/evaluation/data/amc23/amc23.parquet")
data_loader.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import random
4
+ import datasets
5
+ from datasets import load_dataset, Dataset, concatenate_datasets
6
+ from utils import load_jsonl, lower_keys
7
+
8
+
9
+ def load_data(data_name, split, data_dir="./data"):
10
+ data_file = f"{data_dir}/{data_name}/{split}.jsonl"
11
+ if os.path.exists(data_file):
12
+ examples = list(load_jsonl(data_file))
13
+ else:
14
+ if data_name == "math":
15
+ dataset = load_dataset(
16
+ "competition_math",
17
+ split=split,
18
+ name="main",
19
+ cache_dir=f"{data_dir}/temp",
20
+ )
21
+ elif data_name == "gsm8k":
22
+ dataset = load_dataset(data_name, split=split)
23
+ elif data_name == "svamp":
24
+ # evaluate on training set + test set
25
+ dataset = load_dataset("ChilleD/SVAMP", split="train")
26
+ dataset = concatenate_datasets(
27
+ [dataset, load_dataset("ChilleD/SVAMP", split="test")]
28
+ )
29
+ elif data_name == "asdiv":
30
+ dataset = load_dataset("EleutherAI/asdiv", split="validation")
31
+ dataset = dataset.filter(
32
+ lambda x: ";" not in x["answer"]
33
+ ) # remove multi-answer examples
34
+ elif data_name == "mawps":
35
+ examples = []
36
+ # four sub-tasks
37
+ for data_name in ["singleeq", "singleop", "addsub", "multiarith"]:
38
+ sub_examples = list(load_jsonl(f"{data_dir}/mawps/{data_name}.jsonl"))
39
+ for example in sub_examples:
40
+ example["type"] = data_name
41
+ examples.extend(sub_examples)
42
+ dataset = Dataset.from_list(examples)
43
+ elif data_name == "mmlu_stem":
44
+ dataset = load_dataset("hails/mmlu_no_train", "all", split="test")
45
+ # only keep stem subjects
46
+ stem_subjects = [
47
+ "abstract_algebra",
48
+ "astronomy",
49
+ "college_biology",
50
+ "college_chemistry",
51
+ "college_computer_science",
52
+ "college_mathematics",
53
+ "college_physics",
54
+ "computer_security",
55
+ "conceptual_physics",
56
+ "electrical_engineering",
57
+ "elementary_mathematics",
58
+ "high_school_biology",
59
+ "high_school_chemistry",
60
+ "high_school_computer_science",
61
+ "high_school_mathematics",
62
+ "high_school_physics",
63
+ "high_school_statistics",
64
+ "machine_learning",
65
+ ]
66
+ dataset = dataset.rename_column("subject", "type")
67
+ dataset = dataset.filter(lambda x: x["type"] in stem_subjects)
68
+ elif data_name == "carp_en":
69
+ dataset = load_jsonl(f"{data_dir}/carp_en/test.jsonl")
70
+ else:
71
+ raise NotImplementedError(data_name)
72
+
73
+ examples = list(dataset)
74
+ examples = [lower_keys(example) for example in examples]
75
+ dataset = Dataset.from_list(examples)
76
+ os.makedirs(f"{data_dir}/{data_name}", exist_ok=True)
77
+ dataset.to_json(data_file)
78
+
79
+ # add 'idx' in the first column
80
+ if "idx" not in examples[0]:
81
+ examples = [{"idx": i, **example} for i, example in enumerate(examples)]
82
+
83
+ # dedepulicate & sort
84
+ examples = sorted(examples, key=lambda x: x["idx"])
85
+ return examples
eval_tools.py ADDED
@@ -0,0 +1,470 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ def apply_RL_prompt(chunk, args, budget):
3
+ if args.prompt_type == "deepseek3" and os.environ['tip'] == "Ahead":
4
+ #### Ahead方法为:在问题的末尾加上remaining。
5
+ return RL_deepseek3_prompt(chunk, budget)
6
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt":
7
+ return prompt_format(chunk, budget)
8
+ elif args.prompt_type == "qwen25-math-cot" and os.environ['tip'] == "prompt":
9
+ return prompt_format_qw(chunk, budget)
10
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt-based":
11
+ return deepseek3_prompt_based(chunk, budget)
12
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt-based1":
13
+ return deepseek3_prompt_based1(chunk, budget)
14
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt-based2":
15
+ return deepseek3_prompt_based2(chunk, budget)
16
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "prompt-based3":
17
+ return deepseek3_prompt_based3(chunk, budget)
18
+ elif os.environ['tip'] == "default":
19
+ return chunk
20
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "ATD_A" or os.environ['tip'] == "ATD_R":
21
+ return ATD_A_deepseek3_prompt(chunk, budget)
22
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "TCM":
23
+ return TCM_prompt(chunk, budget)
24
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "TCMv2":
25
+ return TCMv2_prompt(chunk, budget)
26
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "withoutremaining":
27
+ return withoutremaining_prompt(chunk, budget)
28
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "8ratio":
29
+ return _8ratio_prompt(chunk, budget)
30
+ elif args.prompt_type == "deepseek3" and "prompt_v1" in os.environ['tip']:
31
+ return prompt_v1_prompt(chunk, budget)
32
+ elif args.prompt_type == "deepseek3" and "prompt_v2" in os.environ['tip']:
33
+ return prompt_v2_prompt(chunk, budget)
34
+ elif args.prompt_type == "deepseek3" and "prompt_cod" in os.environ['tip']:
35
+ return prompt_cod_prompt(chunk, budget)
36
+ elif args.prompt_type == "deepseek3" and "prompt_c2f" in os.environ['tip']:
37
+ return prompt_c2f_prompt(chunk, budget)
38
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "Laser":
39
+ return Laser_prompt(chunk, budget)
40
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "TCM+":
41
+ return TCMv2_prompt(chunk, budget)
42
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "SST":
43
+ return SST_prompt(chunk, budget)
44
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "Tokenskip":
45
+ return Tokenskip_prompt(chunk, budget)
46
+ elif args.prompt_type == "deepseek3" and os.environ['tip'] == "thinkprune":
47
+ return thinkprune_prompt(chunk, budget)
48
+ else:
49
+ return chunk
50
+
51
+
52
+
53
+
54
+
55
+ def Tokenskip_prompt(chunk, budget):
56
+ find_strings = "<|Assistant|>"
57
+ alpha = os.environ['alpha']
58
+ for i in range(len(chunk)):
59
+ head = chunk[i].split(find_strings)[0]
60
+ tail = chunk[i].split(find_strings)[1]
61
+ add_prompt = f'<|end▁of▁sentence|>{alpha}<|end▁of▁sentence|>'
62
+ chunk[i] = head + add_prompt + find_strings + tail
63
+ return chunk
64
+
65
+
66
+ def SST_prompt(chunk, budget):
67
+ find_strings = "<|Assistant|>"
68
+ up_to_50 = budget // 50 + 1
69
+ N = up_to_50
70
+ for i in range(len(chunk)):
71
+ head = chunk[i].split(find_strings)[0]
72
+ tail = chunk[i].split(find_strings)[1]
73
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
74
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
75
+ add_prompt = f"\n(Complete thinking within {N} <countdown> or fewer.)"
76
+ # add_prompt = f'\n<remaining>{budget}</remaining>\n'
77
+
78
+ add_response = "\n<think>\n\n<countdown>\n"
79
+ # head += f"\n<remaining>{budget}</remaining>\n"
80
+ chunk[i] = head + add_prompt + find_strings + tail + add_response
81
+ # print(f"chunk[i] = {chunk[i]}")
82
+ return chunk
83
+
84
+
85
+ def TCMv2_prompt(chunk, budget):
86
+ find_strings = "<|Assistant|>"
87
+ for i in range(len(chunk)):
88
+ head = chunk[i].split(find_strings)[0]
89
+ tail = chunk[i].split(find_strings)[1]
90
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
91
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
92
+ add_prompt = f"\n(Complete thinking within \n<remaining>{budget}</remaining>\n tokens or fewer.)"
93
+ # add_prompt = f'\n<remaining>{budget}</remaining>\n'
94
+
95
+ add_response = f""
96
+ # head += f"\n<remaining>{budget}</remaining>\n"
97
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
98
+ # print(f"chunk[i] = {chunk[i]}")
99
+ return chunk
100
+
101
+
102
+
103
+ def withoutremaining_prompt(chunk, budget):
104
+ find_strings = "<|Assistant|>"
105
+ for i in range(len(chunk)):
106
+ head = chunk[i].split(find_strings)[0]
107
+ tail = chunk[i].split(find_strings)[1]
108
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
109
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
110
+ add_prompt = f"\n(Complete thinking within {budget} tokens or fewer.)"
111
+ # add_prompt = f'\n<remaining>{budget}</remaining>\n'
112
+
113
+ add_response = f""
114
+ # head += f"\n<remaining>{budget}</remaining>\n"
115
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
116
+ # print(f"chunk[i] = {chunk[i]}")
117
+ return chunk
118
+
119
+ def _8ratio_prompt(chunk, budget):
120
+ os.environ['budget'] = str(budget)
121
+ print(f"budget = {budget}")
122
+ find_strings = "<|Assistant|>"
123
+ for i in range(len(chunk)):
124
+ head = chunk[i].split(find_strings)[0]
125
+ tail = chunk[i].split(find_strings)[1]
126
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
127
+ add_prompt = f"\n(Complete thinking within {budget} tokens or fewer, 7 special tokens ( \n<remaining>7/8</remaining>\n , \n<remaining>6/8</remaining>\n , \n<remaining>5/8</remaining>\n , \n<remaining>4/8</remaining>\n , \n<remaining>3/8</remaining>\n , \n<remaining>2/8</remaining>\n , \n<remaining>1/8</remaining>\n ) will split the thinking process into 8 parts.)"
128
+
129
+ add_response = f""
130
+
131
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
132
+
133
+ return chunk
134
+
135
+ def Laser_prompt(chunk, budget):
136
+ os.environ['budget'] = str(budget)
137
+ print(f"budget = {budget}")
138
+ find_strings = "<|Assistant|>"
139
+ for i in range(len(chunk)):
140
+ head = chunk[i].split(find_strings)[0]
141
+ tail = chunk[i].split(find_strings)[1]
142
+ add_prompt = "Please reason step by step, and put your final answer within \\boxed{}"
143
+ add_response = f""
144
+
145
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
146
+ return chunk
147
+
148
+ def prompt_v1_prompt(chunk, budget):
149
+ os.environ['budget'] = str(budget)
150
+ print(f"budget = {budget}")
151
+ find_strings = "<|Assistant|>"
152
+ for i in range(len(chunk)):
153
+ head = chunk[i].split(find_strings)[0]
154
+ tail = chunk[i].split(find_strings)[1]
155
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
156
+ add_prompt = f"\n(Complete thinking within {budget} tokens or fewer, please output the remaining number of tokens every 200 tokens to facilitate control of the remaining length of the thinking process, here is a template: 'now remaining tokens: xxx', xxx is the real remaining number of tokens.)"
157
+ add_response = f""
158
+
159
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
160
+
161
+ return chunk
162
+
163
+ def prompt_v2_prompt(chunk, budget):
164
+ os.environ['budget'] = str(budget)
165
+ print(f"budget = {budget}")
166
+ find_strings = "<|Assistant|>"
167
+ for i in range(len(chunk)):
168
+ head = chunk[i].split(find_strings)[0]
169
+ tail = chunk[i].split(find_strings)[1]
170
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
171
+ add_prompt = f"\n(Complete thinking within {budget} tokens or fewer)"
172
+ add_response = f""
173
+
174
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
175
+
176
+ return chunk
177
+
178
+ def prompt_cod_prompt(chunk, budget):
179
+ os.environ['budget'] = str(budget)
180
+ print(f"budget = {budget}")
181
+ find_strings = "<|Assistant|>"
182
+ for i in range(len(chunk)):
183
+ head = chunk[i].split(find_strings)[0]
184
+ tail = chunk[i].split(find_strings)[1]
185
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
186
+ add_prompt = f'''
187
+ Please solve the following math problem step by step, but only record the most essential steps during the reasoning process. Each step should be concise and clear, focusing directly on the core calculation or logical transformation. No detailed explanation is needed; just write down the key derivations. After completing the reasoning, provide the final answer after.
188
+
189
+ Example:
190
+ Problem: Jason has 20 lollipops. After giving some to Denny, he now has 12 left. How many did he give to Denny?
191
+ Reasoning:
192
+ 20 - x = 12
193
+ x = 20 - 12
194
+ x = 8
195
+ 8
196
+ Now please solve the above problem.\n(Complete thinking within {budget} tokens or fewer)
197
+ '''
198
+ add_response = f""
199
+
200
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
201
+
202
+ return chunk
203
+
204
+ def prompt_c2f_prompt(chunk, budget):
205
+ os.environ['budget'] = str(budget)
206
+ print(f"budget = {budget}")
207
+ find_strings = "<|Assistant|>"
208
+ for i in range(len(chunk)):
209
+ head = chunk[i].split(find_strings)[0]
210
+ tail = chunk[i].split(find_strings)[1]
211
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
212
+ add_prompt = f'''
213
+ Use the following pattern to solve the problem:
214
+
215
+ **Coarse-Grained Reasoning**
216
+ Provide a brief analysis and initial answer, focusing
217
+ on efficiency and conciseness.
218
+
219
+ **Fine-Grained Reasoning**
220
+ Provide detailed reasoning step by step and a refined
221
+ answer, focusing on correctness and rigor.
222
+
223
+ Conclude with:
224
+ Therefore, the final answer is: \\boxed{{[answer]}}.
225
+ Where [answer] is just the final number or expression
226
+ that solves the problem.
227
+
228
+ Now please solve the above problem.\n(Complete thinking within {budget} tokens or fewer)
229
+ '''
230
+ add_response = f""
231
+
232
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
233
+
234
+ return chunk
235
+
236
+
237
+
238
+
239
+ def thinkprune_prompt(chunk, budget):
240
+ SYSTEM_PROMPT = (
241
+ "A conversation between User and Assistant. The user asks a question, "
242
+ "and the Assistant solves it."
243
+ " The assistant first thinks about the reasoning process in the mind and then provides the user"
244
+ " with the answer. The reasoning process and answer are enclosed within <think></think> and"
245
+ " <answer></answer> tags, respectively, i.e., <think> reasoning process here</think>"
246
+ "<answer> answer here</answer>."
247
+ )
248
+ find_strings = "<|Assistant|>"
249
+ for i in range(len(chunk)):
250
+ head = chunk[i].split(find_strings)[0]
251
+ tail = chunk[i].split(find_strings)[1]
252
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
253
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
254
+ add_prompt = SYSTEM_PROMPT + f"The output of the assistant should be within {budget} tokens"
255
+ # add_prompt = f'\n<remaining>{budget}</remaining>\n'
256
+
257
+ add_response = f""
258
+ # head += f"\n<remaining>{budget}</remaining>\n"
259
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
260
+ # print(f"chunk[i] = {chunk[i]}")
261
+ return chunk
262
+
263
+ def TCM_prompt(chunk, budget):
264
+ find_strings = "<|Assistant|>"
265
+ for i in range(len(chunk)):
266
+ head = chunk[i].split(find_strings)[0]
267
+ tail = chunk[i].split(find_strings)[1]
268
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)'
269
+ add_prompt = f"\n(Complete thinking within \n<remaining>{budget}</remaining>\n tokens or fewer.)"
270
+ # add_prompt = f'\n(Complete thinking within {budget} tokens or fewer.)\n<remaining>{budget}</remaining>\n'
271
+ # add_prompt = f'\n<remaining>{budget}</remaining>\n'
272
+ add_response = f""
273
+ # head += f"\n<remaining>{budget}</remaining>\n"
274
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
275
+ # print(f"chunk[i] = {chunk[i]}")
276
+ return chunk
277
+
278
+
279
+ def prompt_format(chunk, budget):
280
+ '''
281
+ <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates.
282
+ Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
283
+ <|Assistant|>
284
+ '''
285
+ find_strings = "<|Assistant|>"
286
+ for i in range(len(chunk)):
287
+ head = chunk[i].split(find_strings)[0]
288
+ tail = chunk[i].split(find_strings)[1]
289
+ head += f"\n(Complete thinking within {budget} tokens or fewer.)\n"
290
+ chunk[i] = head + find_strings + tail
291
+ return chunk
292
+
293
+
294
+ def prompt_format_qw(chunk, budget):
295
+ '''
296
+ <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates.
297
+ Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
298
+ <|Assistant|>
299
+ '''
300
+ find_strings = "<|im_start|>assistant"
301
+
302
+ for i in range(len(chunk)):
303
+ head = chunk[i].split(find_strings)[0]
304
+ tail = chunk[i].split(find_strings)[1]
305
+ head += f"\n(Complete thinking within {budget} tokens or fewer.)\n"
306
+ chunk[i] = head + find_strings + tail
307
+ return chunk
308
+
309
+
310
+
311
+
312
+
313
+ def ATD_A_deepseek3_prompt(chunk, budget):
314
+ find_strings = "<|Assistant|>"
315
+ for i in range(len(chunk)):
316
+ head = chunk[i].split(find_strings)[0]
317
+ tail = chunk[i].split(find_strings)[1]
318
+ add_prompt = f'\n(Respond in {budget} tokens or fewer. Complete the process between <think> and </think> within the token budget. Display the countdown exponentially as <remaining>xxx</remaining>, where xxx = 50 * 2^n, n >= 0. Think more concisely as countdown decreases.)\n'
319
+ add_response = f"\n(I will complete the process within {budget} tokens and show the countdown as <remaining>xxx</remaining>, following the exponential rule.I will think more concisely as countdown decreases.)\n"
320
+ # head += f"\n<remaining>{budget}</remaining>\n"
321
+ chunk[i] = head + add_prompt + find_strings + add_response + tail
322
+ return chunk
323
+
324
+
325
+
326
+
327
+ def RL_deepseek3_prompt(chunk, budget):
328
+ '''
329
+ <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates.
330
+ Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
331
+ <|Assistant|>
332
+ '''
333
+ find_strings = "<|Assistant|>"
334
+ for i in range(len(chunk)):
335
+ head = chunk[i].split(find_strings)[0]
336
+ tail = chunk[i].split(find_strings)[1]
337
+ head += f"(Please respond in {budget} tokens or fewer)\n"
338
+ # head += f"\n<remaining>{budget}</remaining>\n"
339
+ chunk[i] = head + find_strings + tail
340
+ return chunk
341
+
342
+
343
+ def deepseek3_prompt_based(chunk, budget):
344
+ '''
345
+ <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates.
346
+ Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
347
+ <|Assistant|>
348
+ '''
349
+ find_strings = "<|Assistant|>"
350
+ for i in range(len(chunk)):
351
+ head = chunk[i].split(find_strings)[0]
352
+ tail = chunk[i].split(find_strings)[1]
353
+ head += f"You should finish thinking with in {budget} tokens.\n"
354
+ chunk[i] = head + find_strings + tail
355
+ return chunk
356
+
357
+
358
+ def deepseek3_prompt_based1(chunk, budget):
359
+ '''
360
+ <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates.
361
+ Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
362
+ <|Assistant|>
363
+ '''
364
+ find_strings = "<|Assistant|>"
365
+ for i in range(len(chunk)):
366
+ head = chunk[i].split(find_strings)[0]
367
+ tail = chunk[i].split(find_strings)[1]
368
+ head += f"(Please respond in {budget} tokens or fewer)\n"
369
+ chunk[i] = head + find_strings + tail
370
+ return chunk
371
+
372
+
373
+
374
+ def deepseek3_prompt_based2(chunk, budget):
375
+ '''
376
+ <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates.
377
+ Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
378
+ <|Assistant|>
379
+ '''
380
+ find_strings = "<|Assistant|>"
381
+ for i in range(len(chunk)):
382
+ head = chunk[i].split(find_strings)[0]
383
+ tail = chunk[i].split(find_strings)[1]
384
+ head += f"(HARD STOP at {budget} tokens)\n"
385
+ chunk[i] = head + find_strings + tail
386
+ return chunk
387
+
388
+
389
+ def deepseek3_prompt_based3(chunk, budget):
390
+ '''
391
+ <|User|>Convert the point $(0,3)$ in rectangular coordinates to polar coordinates.
392
+ Enter your answer in the form $(r,\theta),$ where $r > 0$ and $0 \le \theta < 2 \pi.$
393
+ <|Assistant|>
394
+ '''
395
+ find_strings = "<|Assistant|>"
396
+ for i in range(len(chunk)):
397
+ head = chunk[i].split(find_strings)[0]
398
+ tail = chunk[i].split(find_strings)[1]
399
+ head += f"(Response length limit: Strictly {budget} tokens max. Budget cannot be exceeded)\n"
400
+ chunk[i] = head + find_strings + tail
401
+ return chunk
402
+
403
+
404
+
405
+
406
+
407
+ # def solve_final_answer(chunk):
408
+ # k = 0
409
+ # for i in range(len(chunk)):
410
+ # if "**Final Answer**\\boxed" in chunk[i][:-10] and "<|end▁of▁sentence|>" not in chunk[i]:
411
+ # chunk[i] += "<|end▁of▁sentence|>"
412
+ # k += 1
413
+ # print(f"###added {k} final answer!")
414
+ # return chunk
415
+
416
+ # import re
417
+
418
+ def is_balanced(s: str) -> bool:
419
+ """验证大括号是否成对且正确嵌套"""
420
+ stack = 0
421
+ for char in s:
422
+ if char == "{":
423
+ stack += 1
424
+ elif char == "}":
425
+ stack -= 1
426
+ if stack < 0:
427
+ return False
428
+ return stack == 0
429
+
430
+ def solve_final_answer(chunk: list) -> list:
431
+
432
+ """处理包含嵌套大括号的答案匹配"""
433
+
434
+ end_chunk = []
435
+ open_chunk = []
436
+
437
+ k = 0
438
+ pattern = "**Final Answer**\\boxed{" # 初级匹配
439
+
440
+ for i in range(len(chunk)):
441
+ line = chunk[i]
442
+ if not pattern in line:
443
+ open_chunk.append(chunk[i])
444
+ continue
445
+ # 深度扫描完整结构
446
+ start_idx = line.find('**Final Answer**\\boxed{')
447
+ if start_idx == -1:
448
+ open_chunk.append(chunk[i])
449
+ continue
450
+ # 手动解析嵌套结构
451
+ stack = 1
452
+ end_idx = start_idx + len('**Final Answer**\\boxed{')
453
+ while end_idx < len(line) and stack > 0:
454
+ if line[end_idx] == "{":
455
+ stack += 1
456
+ elif line[end_idx] == "}":
457
+ stack -= 1
458
+ end_idx += 1
459
+
460
+ # 验证闭合状态
461
+ if stack == 0 and is_balanced(line[start_idx:end_idx]):
462
+
463
+ chunk[i] += "<|end▁of▁sentence|>" # 保持原有操作
464
+ k += 1
465
+ end_chunk.append(chunk[i])
466
+ else:
467
+ open_chunk.append(chunk[i])
468
+
469
+ print(f"### Find {k} anwsers have final answer!")
470
+ return chunk, end_chunk, open_chunk
evaluate.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import numpy as np
3
+ from tqdm import tqdm
4
+ from pebble import ProcessPool
5
+ from concurrent.futures import TimeoutError
6
+
7
+ from grader import *
8
+
9
+ from parser import *
10
+ from utils import load_jsonl
11
+ from python_executor import PythonExecutor
12
+
13
+
14
+ def evaluate(data_name, prompt_type, samples: list=None, file_path: str=None, max_num_samples=None, execute=False):
15
+ assert samples or file_path, "samples or file_path must be provided"
16
+ if not samples:
17
+ samples = list(load_jsonl(file_path))
18
+ if 'idx' in samples[0]:
19
+ samples = {sample['idx']: sample for sample in samples}.values()
20
+ samples = sorted(samples, key=lambda x: x['idx'])
21
+ else:
22
+ samples = [dict(idx=idx, **sample) for idx, sample in enumerate(samples)]
23
+
24
+ if max_num_samples:
25
+ print(f"max_num_samples: {max_num_samples} / {len(samples)}")
26
+ samples = samples[:max_num_samples]
27
+
28
+ # parse gt
29
+ for sample in samples:
30
+ sample['gt_cot'], sample['gt'] = parse_ground_truth(sample, data_name)
31
+ params = [(idx, pred, sample['gt']) for idx, sample in enumerate(samples) for pred in sample['pred']]
32
+
33
+ scores = []
34
+ timeout_cnt = 0
35
+
36
+ with ProcessPool(max_workers=1) as pool:
37
+ future = pool.map(math_equal_process, params, timeout=3)
38
+ iterator = future.result()
39
+ with tqdm(total=len(samples), desc="Evaluate") as progress_bar:
40
+ while True:
41
+ try:
42
+ result = next(iterator)
43
+ scores.append(result)
44
+ except StopIteration:
45
+ break
46
+ except TimeoutError as error:
47
+ print(error)
48
+ scores.append(False)
49
+ timeout_cnt += 1
50
+ except Exception as error:
51
+ print(error.traceback)
52
+ exit()
53
+ progress_bar.update(1)
54
+
55
+ idx = 0
56
+ score_mat = []
57
+ print(f"sample['pred'] = {sample['pred']}")
58
+ accu = 0
59
+ for score in scores:
60
+ if score:
61
+ accu += 1
62
+ simple_acc = accu / len(scores) * 100
63
+ print(f"simple_acc = {simple_acc}, true samples = {accu}")
64
+ for sample in samples:
65
+ sample['score'] = scores[idx: idx+len(sample['pred'])]
66
+ assert len(sample['score']) == len(sample['pred'])
67
+ score_mat.append(sample['score'])
68
+ idx += len(sample['pred'])
69
+
70
+ max_len = max([len(s) for s in score_mat])
71
+
72
+ for i, s in enumerate(score_mat):
73
+ if len(s) < max_len:
74
+ score_mat[i] = s + [s[-1]] * (max_len - len(s)) # pad
75
+
76
+ # output mean of each column of scores
77
+ col_means= np.array(score_mat).mean(axis=0)
78
+ mean_score = list(np.round(col_means * 100, decimals=1))
79
+
80
+ result_json = {
81
+ "num_samples": len(samples),
82
+ "num_scores": len(scores),
83
+ "timeout_samples": timeout_cnt,
84
+ "empty_samples": len([s for s in samples if not s['pred'][-1]]),
85
+ "acc": mean_score[0],
86
+ "simple_acc": simple_acc,
87
+ }
88
+
89
+ # each type score
90
+ if "type" in samples[0]:
91
+ type_scores = {}
92
+ for sample in samples:
93
+ if sample['type'] not in type_scores:
94
+ type_scores[sample['type']] = []
95
+ type_scores[sample['type']].append(sample['score'][-1])
96
+ type_scores = {k: np.round(np.array(v).mean() * 100, decimals=1) for k, v in type_scores.items()}
97
+ type_scores = {k: v for k, v in sorted(type_scores.items(), key=lambda item: item[0])}
98
+ result_json['type_acc'] = type_scores
99
+
100
+ print(result_json)
101
+ return samples, result_json
102
+
103
+
104
+ def parse_args():
105
+ parser = argparse.ArgumentParser()
106
+ parser.add_argument("--data_name", type=str, default="math")
107
+ parser.add_argument("--prompt_type", type=str, default="tool-integrated")
108
+ parser.add_argument("--file_path", type=str, default=None, required=True)
109
+ parser.add_argument("--max_num_samples", type=int, default=None)
110
+ parser.add_argument("--execute", action="store_true")
111
+ args = parser.parse_args()
112
+ return args
113
+
114
+ if __name__ == "__main__":
115
+ args = parse_args()
116
+ evaluate(data_name=args.data_name, prompt_type=args.prompt_type, file_path=args.file_path,
117
+ max_num_samples=args.max_num_samples, execute=args.execute)
examples.py ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+
3
+
4
+ def get_examples():
5
+ examples = {}
6
+ examples["gsm8k"] = [
7
+ (
8
+ "There are 15 trees in the grove. Grove workers will plant trees in the grove today. After they are done, there will be 21 trees. How many trees did the grove workers plant today?",
9
+ "There are 15 trees originally. Then there were 21 trees after some more were planted. So there must have been 21 - 15 = 6. The answer is 6.",
10
+ ),
11
+ (
12
+ "If there are 3 cars in the parking lot and 2 more cars arrive, how many cars are in the parking lot?",
13
+ "There are originally 3 cars. 2 more cars arrive. 3 + 2 = 5. The answer is 5.",
14
+ ),
15
+ (
16
+ "Leah had 32 chocolates and her sister had 42. If they ate 35, how many pieces do they have left in total?",
17
+ "Originally, Leah had 32 chocolates. Her sister had 42. So in total they had 32 + 42 = 74. After eating 35, they had 74 - 35 = 39. The answer is 39.",
18
+ ),
19
+ (
20
+ "Jason had 20 lollipops. He gave Denny some lollipops. Now Jason has 12 lollipops. How many lollipops did Jason give to Denny?",
21
+ "Jason started with 20 lollipops. Then he had 12 after giving some to Denny. So he gave Denny 20 - 12 = 8. The answer is 8.",
22
+ ),
23
+ (
24
+ "Shawn has five toys. For Christmas, he got two toys each from his mom and dad. How many toys does he have now?",
25
+ "Shawn started with 5 toys. If he got 2 toys each from his mom and dad, then that is 4 more toys. 5 + 4 = 9. The answer is 9.",
26
+ ),
27
+ (
28
+ "There were nine computers in the server room. Five more computers were installed each day, from monday to thursday. How many computers are now in the server room?",
29
+ "There were originally 9 computers. For each of 4 days, 5 more computers were added. So 5 * 4 = 20 computers were added. 9 + 20 is 29. The answer is 29.",
30
+ ),
31
+ (
32
+ "Michael had 58 golf balls. On tuesday, he lost 23 golf balls. On wednesday, he lost 2 more. How many golf balls did he have at the end of wednesday?",
33
+ "Michael started with 58 golf balls. After losing 23 on tuesday, he had 58 - 23 = 35. After losing 2 more, he had 35 - 2 = 33 golf balls. The answer is 33.",
34
+ ),
35
+ (
36
+ "Olivia has $23. She bought five bagels for $3 each. How much money does she have left?",
37
+ "Olivia had 23 dollars. 5 bagels for 3 dollars each will be 5 x 3 = 15 dollars. So she has 23 - 15 dollars left. 23 - 15 is 8. The answer is 8.",
38
+ ),
39
+ ]
40
+ examples["gsm8k-pal"] = [
41
+ (
42
+ "Olivia has $23. She bought five bagels for $3 each. How much money does she have left?",
43
+ '```python\ndef solution():\n """Olivia has $23. She bought five bagels for $3 each. How much money does she have left?"""\n money_initial = 23\n bagels = 5\n bagel_cost = 3\n money_spent = bagels * bagel_cost\n money_left = money_initial - money_spent\n result = money_left\n return result\n```',
44
+ ),
45
+ (
46
+ "Michael had 58 golf balls. On tuesday, he lost 23 golf balls. On wednesday, he lost 2 more. How many golf balls did he have at the end of wednesday?",
47
+ '```python\ndef solution():\n """Michael had 58 golf balls. On tuesday, he lost 23 golf balls. On wednesday, he lost 2 more. How many golf balls did he have at the end of wednesday?"""\n golf_balls_initial = 58\n golf_balls_lost_tuesday = 23\n golf_balls_lost_wednesday = 2\n golf_balls_left = golf_balls_initial - golf_balls_lost_tuesday - golf_balls_lost_wednesday\n result = golf_balls_left\n return result\n```',
48
+ ),
49
+ (
50
+ "There were nine computers in the server room. Five more computers were installed each day, from monday to thursday. How many computers are now in the server room?",
51
+ '```python\ndef solution():\n """There were nine computers in the server room. Five more computers were installed each day, from monday to thursday. How many computers are now in the server room?"""\n computers_initial = 9\n computers_per_day = 5\n num_days = 4 # 4 days between monday and thursday\n computers_added = computers_per_day * num_days\n computers_total = computers_initial + computers_added\n result = computers_total\n return result\n```',
52
+ ),
53
+ ]
54
+ examples["gsm8k-tora"] = [
55
+ (
56
+ "Olivia has $23. She bought five bagels for $3 each. How much money does she have left?",
57
+ "```python\ndef money_left():\n money_initial = 23\n bagels = 5\n bagel_cost = 3\n money_spent = bagels * bagel_cost\n remaining_money = money_initial - money_spent\n return remaining_money\n \nremaining_money = money_left()\nprint(remaining_money)\n```\n```output\n8\n```\nOlivia has $\\boxed{8}$ dollars left.",
58
+ ),
59
+ (
60
+ "Michael had 58 golf balls. On tuesday, he lost 23 golf balls. On wednesday, he lost 2 more. How many golf balls did he have at the end of wednesday?",
61
+ "```python\ndef remaining_golf_balls():\n golf_balls_initial = 58\n golf_balls_lost_tuesday = 23\n golf_balls_lost_wednesday = 2\n golf_balls_left = golf_balls_initial - golf_balls_lost_tuesday - golf_balls_lost_wednesday\n remaining_golf_balls = golf_balls_left\n return remaining_golf_balls\n\nanswer = remaining_golf_balls() \nprint(answer)\n```\n```output\n33\n```\nMichael had $\\boxed{33}$ golf balls at the end of Wednesday.",
62
+ ),
63
+ (
64
+ "There were nine computers in the server room. Five more computers were installed each day, from monday to thursday. How many computers are now in the server room?",
65
+ "```python\ndef total_computers():\n computers_initial = 9\n computers_per_day = 5\n num_days = 4 # 4 days between monday and thursday\n computers_added = computers_per_day * num_days\n computers_total = computers_initial + computers_added\n return computers_total\n\ntotal_computers = total_computers()\nprint(total_computers)\n```\n```output\n29\n```\nThere're $\\boxed{29}$ computers in the server room.",
66
+ ),
67
+ ]
68
+
69
+ examples["math"] = [
70
+ (
71
+ "Kevin Kangaroo begins hopping on a number line at 0. He wants to get to 1, but he can hop only $\\frac{1}{3}$ of the distance. Each hop tires him out so that he continues to hop $\\frac{1}{3}$ of the remaining distance. How far has he hopped after five hops? Express your answer as a common fraction.",
72
+ "Let's think step by step\nKevin hops $1/3$ of the remaining distance with every hop.\nHis first hop takes $1/3$ closer.\nFor his second hop, he has $2/3$ left to travel, so he hops forward $(2/3)(1/3)$.\nFor his third hop, he has $(2/3)^2$ left to travel, so he hops forward $(2/3)^2(1/3)$.\nIn general, Kevin hops forward $(2/3)^{k-1}(1/3)$ on his $k$th hop.\nWe want to find how far he has hopped after five hops.\nThis is a finite geometric series with first term $1/3$, common ratio $2/3$, and five terms.\nThus, Kevin has hopped $\\frac{\\frac{1}{3}\\left(1-\\left(\\frac{2}{3}\\right)^5\\right)}{1-\\frac{2}{3}} = \\boxed{\\frac{211}{243}}$.\nThe answer is \\frac{211}{243}}",
73
+ ),
74
+ (
75
+ "What is the area of the region defined by the equation $x^2+y^2 - 7 = 4y-14x+3$?",
76
+ "Let's think step by step\nWe rewrite the equation as $x^2 + 14x + y^2 - 4y = 10$ and then complete the square,\nresulting in $(x+7)^2-49 + (y-2)^2-4=10$,\nor $(x+7)^2+(y-2)^2=63$.\nThis is the equation of a circle with center $(-7, 2)$ and radius $\\sqrt{63},$\nso the area of this region is $\\pi r^2 = \\boxed{63\\pi}$.\nThe answer is 63\\pi",
77
+ ),
78
+ (
79
+ "If $x^2+y^2=1$, what is the largest possible value of $|x|+|y|$?",
80
+ "Let's think step by step\nIf $(x,y)$ lies on the circle,\nso does $(x,-y),$ $(-x,-y),$ and $(-x,-y),$ (which all give the same value of $|x| + |y|$),\nso we can assume that $x \\ge 0$ and $y \\ge 0.$\nThen $|x| + |y| = x + y.$ Squaring, we get\n\\[(x + y)^2 = x^2 + 2xy + y^2 = 1 + 2xy.\\]\nNote that $(x - y)^2 \\ge 0.$\nExpanding, we get $x^2 - 2xy + y^2 \\ge 0,$ so $2xy \\le x^2 + y^2 = 1.$\nHence,\\[1 + 2xy \\le 2,\\]which means $x + y \\le \\sqrt{2}.$\nEquality occurs when $x = y = \\frac{1}{\\sqrt{2}},$\nso the maximum value of $|x| + |y|$ is $\\boxed{\\sqrt{2}}.$\nThe answer is \\sqrt{2}",
81
+ ),
82
+ (
83
+ "If $f(x)=\\frac{ax+b}{cx+d}, abcd\\not=0$ and $f(f(x))=x$ for all $x$ in the domain of $f$, what is the value of $a+d$?",
84
+ "Let's think step by step\nThe condition $f(f(x))$ means that $f$ is the inverse of itself,\nso its graph is symmetrical about the line $y = x$.\nWith a rational function of this form, we will have two asymptotes:\na vertical one at $x=-d/c$ if $cx+d$ does not divide $ax+b$,\nand a horizontal one at $y=a/c$,\nif we take the limit of $f(x)$ as $x$ goes to $\\pm\\infty$.\nIn order for $f$ to be its own inverse, the intersection of the asymptotes must lie on the line $y=x$\nso that it and its asymptotes reflect onto themselves.\nThis means that $-d/c=a/c$,\nand therefore $-d=a$ and $a+d=\\boxed{0}$.\nThe answer is 0",
85
+ ),
86
+ (
87
+ "Expand $(2z^2 + 5z - 6)(3z^3 - 2z + 1)$.",
88
+ "Let's think step by step\n$$\\begin{array}{crrrrrrr}\n& & & 3z^3 & & -2z & + 1 & \\\\\n\\times & & & & 2z^2 & +5z & -6 \\\\\n\\cline{1-7}\\rule{0pt}{0.17in}\n& & & -18z^3 & & +12z & -6 & \\\\\n& & +15z^4 & & -10z^2 & +5z & & \\\\\n+ & 6z^5 & & -4z^3 & +2z^2 & & & \\\\\n\\cline{1-7}\\rule{0pt}{0.17in}\n& 6z^5 & +15z^4 & -22z^3 & - 8z^2 &+17z & -6 &\n\\end{array}$$\nThe answer is 6z^5+15z^4-22z^3-8z^2+17z-6",
89
+ ),
90
+ ]
91
+
92
+ examples["math_pal"] = [
93
+ (
94
+ "Display the final result in LaTeX.\n\n Find the coefficient of $x^3$ when $3(x^2 - x^3+x) +3(x +2x^3- 3x^2 + 3x^5+x^3) -5(1+x-4x^3 - x^2)$ is simplifie.",
95
+ "```python\nfrom sympy import symbols, simplify\n\ndef solution():\n x = symbols('x')\n expr = 3*(x**2 - x**3 + x) + 3*(x + 2*x**3 - 3*x**2 + 3*x**5 + x**3) - 5*(1 + x - 4*x**3 - x**2)\n simplified_expr = simplify(expr)\n\n x3_coefficient = simplified_expr.as_coefficients_dict()[x**3]\n result = x3_coefficient\n return result\n```",
96
+ ),
97
+ (
98
+ "The surface area of a sphere with radius $r$ is $4\\pi r^2$. Including the area of its circular base, what is the total surface area of a hemisphere with radius 6 cm? Express your answer in terms of $\\pi$.",
99
+ "```python\nimport math\n\ndef solution():\n radius = 6\n\n # Surface area of the hemisphere\n hemisphere_area = 2 * math.pi * radius**2\n\n # Area of the circular base\n base_area = math.pi * radius**2\n\n # Total surface area\n total_surface_area = hemisphere_area + base_area\n\n # Formatting the result in LaTeX\n result = r'{}\\\\pi'.format(total_surface_area / math.pi)\n return result\n```",
100
+ ),
101
+ (
102
+ "Monica tosses a fair 6-sided die. If the roll is a prime number, then she wins that amount of dollars (so that, for example, if she rolls 3, then she wins 3 dollars). If the roll is composite, she wins nothing. Otherwise, she loses 3 dollars. What is the expected value of her winnings on one die toss? Express your answer as a dollar value to the nearest cent.",
103
+ '```python\ndef solution():\n # Probabilities of each outcome\n prime_prob = 1 / 6\n composite_prob = 1 / 3\n otherwise_prob = 1 / 6\n\n # Expected value of each outcome\n prime_expected_value = (2 * prime_prob) + (3 * prime_prob) + (5 * prime_prob)\n composite_expected_value = 0 * composite_prob\n otherwise_expected_value = -3 * otherwise_prob\n\n # Total expected value\n total_expected_value = prime_expected_value + composite_expected_value + otherwise_expected_value\n\n # Dollar value to the nearest cent\n result = "{:.2f}".format(total_expected_value)\n return result\n```',
104
+ ),
105
+ (
106
+ "Given $\\mathbf{a} = \\begin{pmatrix} -7 \\\\ 0 \\\\ 1 \\end{pmatrix}$ and $\\mathbf{b} = \\begin{pmatrix} 4 \\\\ 2 \\\\ -1 \\end{pmatrix},$ find $\\mathbf{a} - 3 \\mathbf{b}.$",
107
+ "```python\nimport numpy as np\n\ndef solution()\n a = np.array([-7, 0, 1])\n b = np.array([4, 2, -1])\n\n result = a - 3 * b\n\n result = r'\\begin{{pmatrix}} {} \\\\ {} \\\\ {} \\end{{pmatrix}}'.format(result[0], result[1], result[2])\n return result\n```",
108
+ ),
109
+ ]
110
+ examples["math-tora"] = [
111
+ (
112
+ "Convert the point $(0, -3 \\sqrt{3}, 3)$ in rectangular coordinates to spherical coordinates. Enter your answer in the form $(\\rho,\\theta,\\phi),$ where $\\rho > 0,$ $0 \\le \\theta < 2 \\pi,$ and $0 \\le \\phi \\le \\pi.$",
113
+ "To convert the point $(x, y, z)$ in rectangular coordinates to spherical coordinates $(\\rho, \\theta, \\phi)$, we use the following formulas:\n1. $\\rho = \\sqrt{x^2 + y^2 + z^2}$\n2. $\\theta = \\arctan{\\frac{y}{x}}$\n3. $\\phi = \\arccos{\\frac{z}{\\rho}}$\n\nLet's write a function:\n\n```python\nfrom sympy import sqrt, atan2, acos, pi\n\ndef rectangular_to_spherical():\n x, y, z = 0, -3*sqrt(3), 3\n rho = sqrt(x**2 + y**2 + z**2)\n theta = atan2(y, x)\n phi = acos(z/rho)\n return rho, theta, phi\n\nspherical_coordinates = rectangular_to_spherical()\nprint(spherical_coordinates)\n```\n```output\n(6, -pi/2, pi/3)\n```\n\nThe required form of the answer is $(\\rho, \\theta, \\phi)$, where $\\rho > 0$, $0 \\le \\theta < 2\\pi$, and $0 \\le \\phi \\le \\pi$. Since our initial output has $\\theta = -\\pi/2$, which doesn't meet the condition for $\\theta$, we add $2\\pi$ to adjust its value.\n\nHence, the spherical coordinates for the point $(0, -3\\sqrt{3}, 3)$ are $\\boxed{(6, \\frac{3\\pi}{2}, \\frac{\\pi}{3})}$.",
114
+ ),
115
+ (
116
+ "Compute $1011_2 + 101_2 - 1100_2 + 1101_2$. Express your answer in base 2.",
117
+ 'Let\'s write a single python function for binary computation:\n\n```python\ndef binary_sum_diff():\n # Convert binary to decimal\n num1 = int("1011", 2)\n num2 = int("101", 2)\n num3 = int("1100", 2)\n num4 = int("1101", 2)\n\n # Perform the operations\n result = num1 + num2 - num3 + num4\n\n # Convert the result back to binary\n result_binary = format(result, "b")\n\n return result_binary\n\nresult = binary_sum_diff()\nprint(result)\n```\n```output\n10001\n```\nThe answer expressed in base 2 is $\\boxed{10001_2}$.',
118
+ ),
119
+ (
120
+ "Find the matrix that corresponds to projecting onto the vector $\\begin{pmatrix} 2 \\\\ -3 \\end{pmatrix}.$",
121
+ "```python\nfrom sympy import Matrix, simplify\n\ndef projection_matrix():\n v = Matrix([2, -3])\n\n # Calculate the projection matrix\n P = (v * v.T) / (v.T * v)[0]\n\n # Simplify the elements\n P = P.applyfunc(simplify)\n\n return P\n\nresult = projection_matrix()\nprint(result)\n```\n```output\nMatrix([[4/13, -6/13], [-6/13, 9/13]])\n```\n\nThe matrix is $\\boxed{\\begin{pmatrix} \\frac{4}{13} & -\\frac{6}{13} \\ -\\frac{6}{13} & \\frac{9}{13} \\end{pmatrix}}.$",
122
+ ),
123
+ (
124
+ "Solve the inequality\n\\[\\frac{x^2 - 25}{x + 5} < 0.\\]",
125
+ "Let's use `sympy` to solve the inequality:\n\n```python\nfrom sympy import symbols, simplify\nfrom sympy.solvers.inequalities import solve_univariate_inequality\nfrom sympy.core.relational import StrictLessThan\n\ndef solve_inequality():\n x = symbols('x')\n expression = (x**2 - 25) / (x + 5)\n inequality = StrictLessThan(expression, 0)\n solution = solve_univariate_inequality(inequality, x, relational=False)\n simplified_solution = simplify(solution)\n \n return simplified_solution\n\nresult = solve_inequality()\nprint(result)\n```\n```output\nUnion(Interval.open(-oo, -5), Interval.Lopen(-5, 5))\n```\nThe answer is $\\boxed{(-\\infty,-5)\\cup(-5,5)}$",
126
+ ),
127
+ (
128
+ 'In the figure, triangles $ABC$ and $BCD$ are equilateral triangles. What is the value of $AD \\div BC$ when expressed in simplest radical form?\n\n[asy]\ndraw((0,0)--(5,8.7)--(10,0)--cycle);\ndraw((10,0)--(15,8.7)--(5,8.7));\nlabel("$A$",(0,0),SW);\nlabel("$B$",(5,8.7),N);\nlabel("$C$",(10,0),SE);\nlabel("$D$",(15,8.7),NE);\n[/asy]',
129
+ "```python\nfrom sympy import Rational, sqrt, simplify\n\ndef ad_divided_by_bc():\n\n x = Rational(1, 1) # Side length of equilateral triangles\n\n ad_squared = 2 * x**2 * (1 + Rational(1, 2)) # Using the law of cosines with cos(2*pi/3) = -1/2\n ad = sqrt(ad_squared)\n\n bc = x # BC is the side length of the equilateral triangles\n\n simplified_ratio = simplify(ad / bc)\n\n return simplified_ratio\n\nresult = ad_divided_by_bc()\nprint(result)\n```\n```output\nsqrt(3)\n```\nThe value of $AD \\div BC$ is $\\boxed{\\sqrt{3}}$.",
130
+ ),
131
+ ]
132
+ examples["carp_en"] = [
133
+ (
134
+ "If $3 a ^ { m + 2 } b$ and $\\frac { 1 } { 2 } ab ^ { n - 1 }$ are similar terms, then $m + n$ is equal to.",
135
+ "Let's think step by step\n$3 a ^ { m + 2 } b$ and $\\frac { 1 } { 2 } ab ^ { n - 1 }$ are like terms. We can obtain $m + 2 = 1$ and $n - 1 = 1$. Solving for $m$ and $n$, we get $m = - 1$ and $n = 2$. Therefore, $m + n = - 1 + 2 = 1$.\nThe answer is: 1",
136
+ ),
137
+ (
138
+ "The solution to the equation $y - \\frac { y - 1 } { 2 } = - \\frac { y + 2 } { 5 }$ is ____ ?",
139
+ "Let's think step by step\nTo eliminate the denominator, we have $10 y - 5 ( y - 1 ) = - 2 ( y + 2 )$. Expanding the brackets gives $10 y - 5 y + 5 = - 2 y - 4$. Rearranging terms gives $10 y - 5 y + 2 y = - 4 - 5$, which simplifies to $7 y = - 9$. Dividing both sides by 7 gives $y = - \\frac { 9 } { 7 }$.\nThe answer is: y = - \\frac { 9 } { 7 }",
140
+ ),
141
+ (
142
+ "If $( m + 4 ) ^ 2 + | n - 3 | = 0$, then $\\frac { 1 } { 2 } m - n$ = ____?",
143
+ "Let's think step by step\n$\\because ( m + 4 ) ^ 2 + | n - 3 | = 0$, $\\therefore m + 4 = 0$, $n - 3 = 0$, which means $m = - 4$, $n = 3$. Then the original expression equals $- 2 - 3 = - 5$.\nThe answer is: - 5",
144
+ ),
145
+ (
146
+ "Given a quadratic equation in one variable $x$, $x ^ 2 + x + m = 0$, with one root being $x = 1$, what is the other root of this equation?",
147
+ "Let's think step by step\nSuppose the quadratic equation in one variable about $x$ is $x ^ 2 + x + m = 0$, and $\\alpha$ is another real root of the equation. Since one real root of the quadratic equation in one variable about $x$ is $1$, we have $\\alpha + 1 = - 1$. Therefore, $\\alpha = - 2$.\nThe answer is: - 2",
148
+ ),
149
+ (
150
+ "The parabola $y = - 5 { x } ^ 2 + 1$ is translated $2$ units upward and $1$ unit to the left, resulting in the parabola _____.",
151
+ "Let's think step by step\nThe parabola $y = - 5 { x } ^ 2 + 1$ is first shifted upward by 2 units, resulting in $y = - 5 { x } ^ 2 + 3$. Then it is shifted left by 1 unit, resulting in $y = - 5 {( x + 1 )} ^ 2 + 3$.\nThe answer is: y = - 5 ( x + 1 ) ^ { 2 } + 3",
152
+ ),
153
+ (
154
+ "If the radical $\\sqrt { x - 8 }$ is defined, then the range of real numbers for $x$ is ____ ?",
155
+ "Let's think step by step\nSince the radical $\\sqrt { x - 8 }$ is defined, therefore $x - 8 \\ge 0$, which implies $x \\ge 8$.\nThe answer is: x \\ge 8",
156
+ ),
157
+ (
158
+ "If $a ^ { m } \\times a ^ { 2 } = a ^ { 7 }$, then the value of $m$ is ____?",
159
+ "Let's think step by step\nAccording to the multiplication rule of powers with the same base: when multiplying powers with the same base, keep the base the same and add the exponents. We have $m + 2 = 7$, so solving for $m$ gives $m = 5$.\nThe answer is: 5",
160
+ ),
161
+ (
162
+ "If line segment $a$ and $b$ satisfy $\\frac { a } { b } = \\frac { 5 } { 2 }$, then the value of $\\frac { a - b } { b }$ is ____?",
163
+ "Let's think step by step\n$\\because \\frac { a } { b } = \\frac { 5 } { 2 }$, $\\therefore$ we can assume $a = 5 k$, then $b = 2 k$, $\\therefore \\frac { a - b } { b } = \\frac { 5 k - 2 k } { 2 k } = \\frac { 3 } { 2 }$.\nThe answer is: \\frac { 3 } { 2 }",
164
+ ),
165
+ ]
166
+
167
+ examples["minerva_math"] = [
168
+ (
169
+ "Find the domain of the expression $\\frac{\\sqrt{x-2}}{\\sqrt{5-x}}$.}",
170
+ "The expressions inside each square root must be non-negative.\nTherefore, $x-2 \\ge 0$, so $x\\ge2$, and $5 - x \\ge 0$, so $x \\le 5$.\nAlso, the denominator cannot be equal to zero, so $5-x>0$, which gives $x<5$.\nTherefore, the domain of the expression is $\\boxed{[2,5)}$.",
171
+ ),
172
+ (
173
+ "If $\\det \\mathbf{A} = 2$ and $\\det \\mathbf{B} = 12,$ then find $\\det (\\mathbf{A} \\mathbf{B}).$",
174
+ "We have that $\\det (\\mathbf{A} \\mathbf{B}) = (\\det \\mathbf{A})(\\det \\mathbf{B}) = (2)(12) = \\boxed{24}.$",
175
+ ),
176
+ (
177
+ "Terrell usually lifts two 20-pound weights 12 times. If he uses two 15-pound weights instead, how many times must Terrell lift them in order to lift the same total weight?",
178
+ "If Terrell lifts two 20-pound weights 12 times, he lifts a total of $2\\cdot 12\\cdot20=480$ pounds of weight. If he lifts two 15-pound weights instead for $n$ times, he will lift a total of $2\\cdot15\\cdot n=30n$ pounds of weight. Equating this to 480 pounds, we can solve for $n$: \\begin{align*}\n30n&=480\\\\\\\n\\Rightarrow\\qquad n&=480/30=\\boxed{16}\n\\end{align*}",
179
+ ),
180
+ (
181
+ "If the system of equations\n\n\\begin{align*}\n6x-4y&=a,\\\\\\\n6y-9x &=b.\n\\end{align*}has a solution $(x, y)$ where $x$ and $y$ are both nonzero, find $\\frac{a}{b},$ assuming $b$ is nonzero.",
182
+ "If we multiply the first equation by $-\\frac{3}{2}$, we obtain\n\n$$6y-9x=-\\frac{3}{2}a.$$Since we also know that $6y-9x=b$, we have\n\n$$-\\frac{3}{2}a=b\\Rightarrow\\frac{a}{b}=\\boxed{-\\frac{2}{3}}.$$",
183
+ ),
184
+ ]
185
+
186
+ examples["aqua"] = [
187
+ (
188
+ "John found that the average of 15 numbers is 40. If 10 is added to each number then the mean of the numbers is?\nAnswer Choices: (A) 50 (B) 45 (C) 65 (D) 78 (E) 64",
189
+ "If 10 is added to each number, then the mean of the numbers also increases by 10. So the new mean would be 50. The answer is (A).",
190
+ ),
191
+ (
192
+ "If a / b = 3/4 and 8a + 5b = 22,then find the value of a.\nAnswer Choices: (A) 1/2 (B) 3/2 (C) 5/2 (D) 4/2 (E) 7/2",
193
+ "a / b = 3/4, then b = 4a / 3. So 8a + 5(4a / 3) = 22. This simplifies to 8a + 20a / 3 = 22, which means 44a / 3 = 22. So a is equal to 3/2. The answer is (B).",
194
+ ),
195
+ (
196
+ "A person is traveling at 20 km/hr and reached his destiny in 2.5 hr then find the distance?\nAnswer Choices: (A) 53 km (B) 55 km (C) 52 km (D) 60 km (E) 50 km",
197
+ "The distance that the person traveled would have been 20 km/hr * 2.5 hrs = 50 km. The answer is (E).",
198
+ ),
199
+ (
200
+ "How many keystrokes are needed to type the numbers from 1 to 500?\nAnswer Choices: (A) 1156 (B) 1392 (C) 1480 (D) 1562 (E) 1788",
201
+ "There are 9 one-digit numbers from 1 to 9. There are 90 two-digit numbers from 10 to 99. There are 401 three-digit numbers from 100 to 500. 9 + 90(2) + 401(3) = 1392. The answer is (B).",
202
+ ),
203
+ ]
204
+ examples["sat_math"] = [
205
+ (
206
+ "If $\frac{x-1}{3}=k$ and $k=3$, what is the value of $x$ ? \nAnswer Choices: (A) 2 (B) 4 (C) 9 (D) 10",
207
+ "If k = 3, then x - 1 = 3 * 3, therfore, x - 1 = 9 and x = 10. The answer is D",
208
+ ),
209
+ (
210
+ "For $i=\\sqrt{-1}$, what is the sum $(7+3 i)+(-8+9 i)$ ? \nAnswer Choices: (A) $-1+12 i$ (B) $-1-6 i$ (C) $15+12 i$ (D) $15-6 i$ 3",
211
+ "For (7+3 i)+(-8+9 i), the real part is 7 + (-8) = -1, the imageinary part is 3 i + 9 i = 12 i. The answer is A",
212
+ ),
213
+ (
214
+ "On Saturday afternoon, Armand sent $m$ text messages each hour for 5 hours, and Tyrone sent $p$ text messages each hour for 4 hours. Which of the following represents the total number of messages sent by Armand and Tyrone on Saturday afternoon?\nAnswer Choices: (A) $9 m p$ (B) $20 m p$ (C) $5 m+4 p$ (D) $4 m+5 p$",
215
+ "Armand texts m messages each hour for 5 hours, which leads to 5m messages. Tyrone texts p messages each hour for 4 hours, which leds to 4p messages. The total is 5m + 4p. The answer is C.",
216
+ ),
217
+ (
218
+ "$$\begin{array}{r}3 x+4 y=-23 \\2 y-x=-19\\end{array}$$What is the solution $(x, y)$ to the system of equations above?\nAnswer Choices: (A) $(-5,-2)$ (B) $(3,-8)$ (C) $(4,-6)$ (D) $(9,-6)$",
219
+ "By solving this equation, we found that x = 3 and y = -8. The answer is B.",
220
+ ),
221
+ ]
222
+ examples["mmlu_mathematics"] = [
223
+ (
224
+ "Simplify and write the result with a rational denominator: $$\\sqrt{\\sqrt[3]{\\sqrt{\frac{1}{729}}}}$$\nAnswer Choices: (A) \\frac{3\\sqrt{3}}{3} (B) \\frac{1}{3} (C) \\sqrt{3} (D) \\frac{\\sqrt{3}}{3}",
225
+ "Factoring $729=3^6$ and combining the roots $\frac{1}{2}\frac{1}{3}\frac{1}{2}=\frac{1}{12}$, we get that $\\sqrt{\\sqrt[3]{\\sqrt{\frac{1}{729}}}}=\\left(\frac{1}{3^6}\right)^{\frac{1}{12}}=\frac{1}{3^{\frac{1}{2}}}=\frac{3}{\\sqrt{3}}$. The answer is (D).",
226
+ ),
227
+ (
228
+ "Five thousand dollars compounded annually at an $x\\%$ interest rate takes six years to double. At the same interest rate, how many years will it take $\\$300$ to grow to $\\$9600$?\nAnswer Choices:(A) 12 (B) 1 (C) 30 (D) 5",
229
+ "To go from $\\$300$ to $\\$9600$, the value must go up by a factor of $9600/300=32=2^5$. Since at this interest rate it takes six years for it to double, it will take $5*6=30$ years to grow to $\\$9600$. The answer is (C).",
230
+ ),
231
+ (
232
+ "Ten students take a biology test and receive the following scores: 45, 55, 50, 70, 65, 80, 40, 90, 70, 85. What is the mean of the students’ test scores?\nAnswer Choices: (A) 55 (B) 60 (C) 62 (D) 65",
233
+ "There are 10 students and the sum of their scores is $45 + 55 + 50 + 70 + 65 + 80 + 40 + 90 + 70 + 85 = 650$, the mean is $650/10=65$. The answer is (D).",
234
+ ),
235
+ (
236
+ "The variable $x$ varies directly as the square of $y$, and $y$ varies directly as the cube of $z$. If $x$ equals $-16$ when $z$ equals 2, what is the value of $x$ when $z$ equals $\frac{1}{2}$?\nAnswer Choices: (A) -1 (B) 16 (C) -\frac{1}{256} (D) \\frac{1}{16}",
237
+ "We know that $x \\propto y^2$ and $y \\propto z^3$, so $x = k z^6$ for some constant $k$. Plugging in for $x=-16$ and $z=2$, the constant value is $k=\frac{x}{z^6}=\frac{-16}{64}=-\frac{1}{4}$. So, when $z=\frac{1}{2}$, the value of $x$ is $x=kz^6=-\frac{1}{4}\frac{1}{2^6}=-\frac{1}{256}$. The answer is (C).",
238
+ ),
239
+ (
240
+ "Joe was in charge of lights for a dance. The red light blinks every two seconds, the yellow light every three seconds, and the blue light every five seconds. If we include the very beginning and very end of the dance, how many times during a seven minute dance will all the lights come on at the same time? (Assume that all three lights blink simultaneously at the very beginning of the dance.)\nAnswer Choices: (A) 3 (B) 15 (C) 6 (D) 5",
241
+ "The least common multiple of 2, 3 and 5 is 30, so during a 7 minute dance, all the three lights will come on at the same time $2*7+1=15$ times. The answer is (B).",
242
+ ),
243
+ ]
244
+ examples["mmlu_physics"] = [
245
+ (
246
+ "A microwave oven is connected to an outlet, 120 V, and draws a current of 2 amps. At what rate is energy being used by the microwave oven?\nAnswer Choices: (A) 10 W (B) 30 W (C) 60 W (D) 240 W",
247
+ "Rate of energy usage is known as power; in an dissipative electrical circuit, power is given by voltage times current. So in our case, the power is 120 V times 2 amps, or 240 W. The answer is (D).",
248
+ ),
249
+ (
250
+ "A point charge, Q = +1 mC, is fixed at the origin. How much work is required to move a charge, Q = +8 µC, from the point (0, 4 meters) to the point (3 meters, 0)?\nAnswer Choices: (A) 3.5 J (B) 6.0 J (C) 22.5 J (D) 40 J",
251
+ "To calculate the work required to move a charge from one location to another in a fixed electric field, it is enough to calculate the potential difference between the two locations. Here, the potential only depends on the distance between the charges; it’s $k q_1 q_2 / r$, where $k$ is Coulomb’s constant. Plugging in values $q_1 = $ 1 mC, $q_2 = 8 \\mu$ C, gives the answer as 5.992 J, which rounds to 6 J. The answer is (B).",
252
+ ),
253
+ (
254
+ "Which of the following conditions will ensure that angular momentum is conserved? I. Conservation of linear momentum II. Zero net external force III. Zero net external torque.\nAnswer Choices: (A) I and II only (B) I and III only (C) II and III only (D) III only",
255
+ "Torque is defined as the change in angular momentum; if there is zero external torque, angular momentum is conserved. The answer is (D).",
256
+ ),
257
+ (
258
+ "A photocell of work function ϕ = 2eV is connected to a resistor in series. Light of frequency f = 1 × 10^15 Hz hits a metal plate of the photocell. If the power of the light is P = 100 W, what is the current through the resistor?\nAnswer Choices: (A) 2:00 AM (B) 6:00 AM (C) 12:00 AM (D) 24 A",
259
+ "The only answer above which has units of current is D, 24 A. The answer is (D).",
260
+ ),
261
+ (
262
+ "A pipe full of air is closed at one end. A standing wave is produced in the pipe, causing the pipe to sound a note. Which of the following is a correct statement about the wave’s properties at the closed end of the pipe?\nAnswer Choices: (A) The pressure is at a node, but the particle displacement is at an antinode. (B) The pressure is at an antinode, but the particle displacement is at a node. (C) The pressure and the particle displacement are both at nodes. (D) The pressure and the particle displacement are both at antinodes.",
263
+ "At the closed end of the pipe, the particles cannot have any net displacement because the pipe closure stops them. So the particle displacement is at a node. This closure also causes the pressure to be maximal, i.e. an antinode. The answer is (B).",
264
+ ),
265
+ ]
266
+ examples["mmlu_chemistry"] = [
267
+ (
268
+ "Which of the following is considered an acid anhydride?\nAnswer Choices: (A) HCl (B) H2SO3 (C) SO2 (D) Al(NO3)3",
269
+ "An acid anhydride is a compound that is derived by removing water from an acid. The chemical formula for water is H2O, which means that we need to determine which of these options, when combined with H2O, forms an acid. SO2, or Sulfur dioxide, when combined with H2O, makes H2SO4, or sulfuric acid. The answer is (C).",
270
+ ),
271
+ (
272
+ "Which of the following is expected to be a polar molecule?\nAnswer Choices: (A) PCl4F (B) BF3 (C) CO2 (D) Si(CH3)4",
273
+ "A polar molecule is one that has a slightly positive charge on one end of the molecule and a slightly negative charge on the other end. Boron trifluoride (BF3) has Boron as the center atom and three fluorine atoms attached to it; it is trigonal planar and symmetric, so it is nonpolar. Carbon Dioxide (CO2) has Carbon as the central atom with double bonds to two Oxygen atoms - this is also symmetrical and therefore nonpolar. The same is the case for tetramethyl silane (SI(CH3)4), which is a Silicon atom surrounded by four methyl groups. The structure of PCL4F is that Phosphorus is the central atom, attached to four chlorines and one fluorine atom. This is asymmetrical, and therefore has a net dipole and is expected to be a polar molecule. The answer is (A).",
274
+ ),
275
+ (
276
+ "From the solubility rules, which of the following is true?\nAnswer Choices: (A) All chlorides, bromides, and iodides are soluble (B) All sulfates are soluble (C) All hydroxides are soluble (D) All ammonium-containing compounds are soluble",
277
+ "The chlorides, bromides, and iodides of lead, silver, and mercury are not soluble in water. This rules out (A). The sulfates of lead, barium, and calcium are not soluble in water, which rules out (B). The hydroxides of any metal besides sodium, potassium, ammonium, calcium, and barium are insoluble. This rules out (C). Typically ammonium ions indicate a soluble ionic substance. The answer is (D).",
278
+ ),
279
+ (
280
+ "A new compound is synthesized and found to be a monoprotic acid with a molar mass of 248 g/mol. When 0.0050 mol of this acid are dissolved in 0.500 L of water, the pH is measured as 3.89. What is the pKa of this acid?\nAnswer Choices: (A) 3.89 (B) 7.78 (C) 5.78 (D) 2.33",
281
+ "Recall that $[A] = [H^{+}]$. Here, this is equal to $$10^{-3.89}$. Then we have $K_{a} = $frac{[H^{+}][A^{-}]}{[HA]} = \\frac{10^{-3.89} \\cdot 10^{-3.89}}{10^{-2}}. The resulting exponent is $-3.89 + (-3.89) - (-2) = 5.78$, therefore $K_a = 10^{-5.78}$. The $pK_a$ is the negative log of $K_a$, which is equal to $5.78$. The answer is (C).",
282
+ ),
283
+ (
284
+ "A solution contains 2.00 mole of acetic acid, CH3COOH, and 1.00 mole of calcium acetate, Ca(CH3COO)2. The solution is able to resist the addition of a small amount of strong acid or strong base with only minor changes in the pH of the solution. Larger quantities of strong acid or strong base can cause a significant change in pH. How many moles of nitric acid, HNO3, may be added before the pH begins to change significantly?\nAnswer Choices: (A) 0.500 mole (B) 1.00 mole (C) 2.00 mole (D) 3.00 mole",
285
+ "We would like to compute the buffer capacity of this solution. First we write the equation for the ionization of the weak acid, in this case of acetic acid. $CH_{3}COOH (aq) + H_{2}O \rightarrow H_{3}O^{+} + CH3COO^{-}$. The conjugate base is therefore the acetate ion. The added strong acid, Nitric acid, will react with the conjugate base. Therefore the maximum amount of acid that can be added will be equal to the amount of acetate ion, or 2 moles. The answer is (C).",
286
+ ),
287
+ ]
288
+ examples["mmlu_biology"] = [
289
+ (
290
+ "In animal cells, which of the following represents the most likely pathway that a secretory protein takes as it is synthesized in a cell?\nAnswer Choices: (A) Plasma membrane–Golgi apparatus–ribosome–secretory vesicle–rough ER (B) Ribosome–Golgi apparatus–rough ER–secretory vesicle–plasma membrane (C) Plasma membrane–Golgi apparatus–ribosome–secretory vesicle–rough ER (D) Ribosome–rough ER–Golgi apparatus–secretory vesicle–plasma membrane",
291
+ "Protein synthesis starts at the ribosome, so we can eliminate (A) and (C). The ribosome is often in the endoplasmic reticulum and moves from there to the Golgi apparatus, where it is modified and packaged into a vesicle. The vesicle then floats to the plasma membrane and is secreted. The answer is (D).",
292
+ ),
293
+ (
294
+ "A mutation in a bacterial enzyme changed a previously polar amino acid into a nonpolar amino acid. This amino acid was located at a site distant from the enzyme’s active site. How might this mutation alter the enzyme’s substrate specificity?\nAnswer Choices: (A) By changing the enzyme’s pH optimum (B) By changing the enzyme’s location in the cell (C) By changing the shape of the protein (D) An amino acid change away from the active site cannot alter the enzyme’s substrate specificity.",
295
+ "A change in an amino acid leads to a change in the primary structure of the protein. A change in the primary structure may lead to a change in the secondary and the tertiary structure of the protein. A change in the tertiary structure means a change in the shape of the protein, so (C) has to be correct. Since the change does not affect the active site of the enzyme, we do not expect the activity of the enzyme to be affected. The answer is (C).",
296
+ ),
297
+ (
298
+ "Which of the following is not a way to form recombinant DNA?\nAnswer Choices: (A) Translation (B) Conjugation (C) Specialized transduction (D) Transformation",
299
+ "The introduction of foreign DNA or RNA into bacteria or eukaryotic cells is a common technique in molecular biology and scientific research. There are multiple ways foreign DNA can be introduced into cells including transformation, transduction, conjugation, and transfection. In contrast, (A) is not a way to form DNA: during translation the ribosomes synthesize proteins from RNA. The answer is (A).",
300
+ ),
301
+ (
302
+ "Homologous structures are often cited as evidence for the process of natural selection. All of the following are examples of homologous structures EXCEPT\nAnswer Choices: (A) the wings of a bird and the wings of a bat (B) the flippers of a whale and the arms of a man (C) the pectoral fins of a porpoise and the flippers of a seal (D) the forelegs of an insect and the forelimbs of a dog",
303
+ "Homologous structures are similar physical features in organisms that share a common ancestor ​​but different functions. Comparisons (B) and (C) are clearly homologous because they share a common ancestor and the structures serve different purposes. Bat wings and birg wings are also homologous, while they are both wings, the forelimbs serve different purposes. Insects and dogs are very far ancestors since one is vertebrate while the other is invertebrate and the forelimbs serve the same purpose, so they are not homologous. The answer is (D).",
304
+ ),
305
+ (
306
+ "Which of the following is not known to be involved in the control of cell division?\nAnswer Choices: (A) Cyclins (B) Protein kinases (C) Checkpoints (D) Fibroblast cells",
307
+ "Normal cells move through the cell cycle in a regulated way. At the checkpoint stage, they use information about their own internal state and cues from the environment around them to decide whether to proceed with cell division. Cues like these act by changing the activity of core cell cycle regulators inside the cell. The most common regulators are cyclins and cyclin-dependent kinases. Fibroblast cells do not play any role in cell division. The answer is (D).",
308
+ ),
309
+ ]
310
+ examples["mmlu_computer"] = [
311
+ (
312
+ "Which of the following is an example of the use of a device on the Internet of Things (IoT) ?\nAnswer Choices: (A) A car alerts a driver that it is about to hit an object. (B) A hiker uses a G P S watch to keep track of her position. (C) A refrigerator orders milk from an online delivery service when the milk in the refrigerator is almost gone. (D) A runner uses a watch with optical sensors to monitor his heart rate.",
313
+ "The term Internet of Things (IoT) refers to common devices which are connected to the internet, enabling new functionality. Choice A is incorrect because it does not describe an internet connected device. In choice B, the watch is only described as having GPS functionality but no internet connectivity. Choice C describes a common device (a refrigerator) which has internet connectivity enabling new functionality (online ordering). Choice D does not mention internet connectivity for the watch, only optical sensors. The answer is (C).",
314
+ ),
315
+ (
316
+ "Many Web browsers allow users to open anonymous windows. During a browsing session in an anonymous window, the browser does not record a browsing history or a list of downloaded files. When the anonymous window is exited, cookies created during the session are deleted. Which of the following statements about browsing sessions in an anonymous window is true?\nAnswer Choices: (A) The activities of a user browsing in an anonymous window will not be visible to people who monitor the user's network, such as the system administrator. (B) Items placed in a Web store's shopping cart for future purchase during the anonymous browsing session will not be saved on the user's computer. (C) A user will not be able to log in to e-mail or social media accounts during the anonymous browsing session. (D) A user browsing in an anonymous window will be protected from viruses launched from any web sites visited or files downloaded.",
317
+ "Choice A is incorrect as it only describes network traffic, which an anonymous browser does not change. Choice B is correct as it correctly describes how an anonymous browser will prevent saving data on the user’s computer after the session is ended. Choice C is incorrect because an anonymous browser will not prevent logging in to email or social media accounts. Choice D is incorrect because an anonymous browser in itself performs no virus protection. The answer is (B).",
318
+ ),
319
+ (
320
+ 'What is the output of "abc"[::-1] in Python 3? \nAnswer Choices: (A) Error (B) abc (C) cba (D) c',
321
+ 'We know that the slicing operator [::-1] takes all of the elements in the string in reverse order, so we reverse the order of the string "abc", resulting in "cba". The answer is (C).',
322
+ ),
323
+ (
324
+ 'In the program below, the initial value of X is 5 and the initial value of Y is 10.\nIF (X < 0){\n DISPLAY ("Foxtrot")\n} ELSE {\n IF (X > Y){\n DISPLAY ("Hotel")\n } ELSE {\n IF (Y > 0){\n DISPLAY ("November")\n } ELSE {\n DISPLAY ("Yankee")\n }\n }\n}\nWhat is displayed as a result of running the program?\nAnswer Choices: (A) Foxtrot (B) Hotel (C) November (D) Yankee',
325
+ 'Because X has the value 5, the first conditional IF (X < 0) is false, so we move to the first ELSE clause. Because X is 5 and Y is 10, the second conditional IF (X > Y) is false, so we move to the following ELSE clause. Since Y is 10, the conditional IF (Y > 0) is true, so the command DISPLAY ("November") is executed. The answer is (C).',
326
+ ),
327
+ (
328
+ "A list of numbers has n elements, indexed from 1 to n. The following algorithm is intended to display the number of elements in the list that have a value greater than 100. The algorithm uses the variables count and position. Steps 3 and 4 are missing.\n Step 1: Set count to 0 and position to 1.\n Step 2: If the value of the element at index position is greater than 100, increase the value of count by 1.\n Step 3: (missing step)\n Step 4: (missing step)\n Step 5: Display the value of count.\nWhich of the following could be used to replace steps 3 and 4 so that the algorithm works as intended?\nAnswer Choices: (A) Step 3: Increase the value of position by 1.\n Step 4: Repeat steps 2 and 3 until the value of count is greater than 100.\n(B) Step 3: Increase the value of position by 1.\n Step 4: Repeat steps 2 and 3 until the value of position is greater than n.\n(C) Step 3: Repeat step 2 until the value of count is greater than 100.\n Step 4: Increase the value of position by 1.\n(D) Step 3: Repeat step 2 until the value of position is greater than n.\n Step 4: Increase the value of count by 1.",
329
+ "Choice A is incorrect, because its Step 4 has an incorrect termination condition, stopping when count is greater than 100. We need to stop after inspecting all elements in the list. Choice B is correct because it correctly increments both count and position, and correctly repeats these steps and terminates when all elements in the list have been inspected. Choice C is incorrect because it incorrectly increments the variable count until its value is greater than 100, regardless of the elements in the list. Choice D is incorrect because its step 3 does not increment the value of position, so it will repeat forever. The answer is (B).",
330
+ ),
331
+ ]
332
+ # mammoth
333
+ examples["mmlu_stem"] = [
334
+ (
335
+ "Simplify and write the result with a rational denominator: $$\\sqrt{\\sqrt[3]{\\sqrt{\frac{1}{729}}}}$$\nAnswer Choices: (A) \\frac{3\\sqrt{3}}{3} (B) \\frac{1}{3} (C) \\sqrt{3} (D) \\frac{\\sqrt{3}}{3}",
336
+ "Factoring $729=3^6$ and combining the roots $\\frac{1}{2}\\frac{1}{3}\\frac{1}{2}=\\frac{1}{12}$, we get that $\\sqrt{\\sqrt[3]{\\sqrt{\frac{1}{729}}}}=\\left(\frac{1}{3^6}\right)^{\frac{1}{12}}=\frac{1}{3^{\frac{1}{2}}}=\frac{3}{\\sqrt{3}}$. The answer is (D).",
337
+ ),
338
+ (
339
+ "In animal cells, which of the following represents the most likely pathway that a secretory protein takes as it is synthesized in a cell?\nAnswer Choices: (A) Plasma membrane–Golgi apparatus–ribosome–secretory vesicle–rough ER (B) Ribosome–Golgi apparatus–rough ER–secretory vesicle–plasma membrane (C) Plasma membrane–Golgi apparatus–ribosome–secretory vesicle–rough ER (D) Ribosome–rough ER–Golgi apparatus–secretory vesicle–plasma membrane",
340
+ "Protein synthesis starts at the ribosome, so we can eliminate (A) and (C). The ribosome is often in the endoplasmic reticulum and moves from there to the Golgi apparatus, where it is modified and packaged into a vesicle. The vesicle then floats to the plasma membrane and is secreted. The answer is (D).",
341
+ ),
342
+ (
343
+ "A microwave oven is connected to an outlet, 120 V, and draws a current of 2 amps. At what rate is energy being used by the microwave oven?\nAnswer Choices: (A) 10 W (B) 30 W (C) 60 W (D) 240 W",
344
+ "Rate of energy usage is known as power; in an dissipative electrical circuit, power is given by voltage times current. So in our case, the power is 120 V times 2 amps, or 240 W. The answer is (D).",
345
+ ),
346
+ (
347
+ "Which of the following is considered an acid anhydride?\nAnswer Choices: (A) HCl (B) H2SO3 (C) SO2 (D) Al(NO3)3",
348
+ "An acid anhydride is a compound that is derived by removing water from an acid. The chemical formula for water is H2O, which means that we need to determine which of these options, when combined with H2O, forms an acid. SO2, or Sulfur dioxide, when combined with H2O, makes H2SO4, or sulfuric acid. The answer is (C).",
349
+ ),
350
+ (
351
+ 'What is the output of "abc"[::-1] in Python 3? \nAnswer Choices: (A) Error (B) abc (C) cba (D) c',
352
+ 'We know that the slicing operator [::-1] takes all of the elements in the string in reverse order, so we reverse the order of the string "abc", resulting in "cba". The answer is (C).',
353
+ ),
354
+ ]
355
+ examples["gaokao"] = [
356
+ (
357
+ "已知 $\\alpha, \\beta, \\gamma$ 是互不相同的锐角, 则在 $\\sin \\alpha \\cos \\beta, \\sin \\beta \\cos \\gamma, \\sin \\gamma \\cos \\alpha$ 三个值中, 大于 $\\frac{1}{2}$ 的个数的最大值是 ( )\n从以下选项中选择:\n(A) 0\n(B) 1\n(C) 2\n(D) 3",
358
+ "1. 如果 $\\alpha, \\beta, \\gamma$ 均小于 $60^\\circ$,那么他们的正弦值都小于 $\\frac{1}{2}$,因此三个值中不可能有大于 $\\frac{1}{2}$ 的值。\n2. 如果有一个角大于 $60^\\circ$,假设为 $\\alpha$,那么对应的正弦值大于 $\\frac{1}{2}$。此时,由于三角形内角和为 $180^\\circ$,所以 $\\beta + \\gamma < 120^\\circ$。这意味着 $\\beta, \\gamma$ 的余弦值均大于 $\\frac{1}{2}$,所以此时 $\\sin \\alpha \\cos \\beta > \\frac{1}{2}, \\sin \\beta \\cos \\gamma > \\frac{1}{2}$。\n3. 如果有两个角大于 $60^\\circ$,例如 $\\alpha$ 和 $\\beta$,那么由于三角形内角和为 $180^\\circ$,我们可以得到 $\\gamma < 60^\\circ$,此时 $\\sin \\gamma < \\frac{1}{2}$。由于 $\\alpha$ 和 $\\beta$ 的余弦值都小于 $\\frac{1}{2}$,因此三个值中不可能有大于 $\\frac{1}{2}$ 的值。\n4. 如果三个角都大于 $60^\\circ$,显然不符合题意。\n综上所述,当有一个角大于 $60^\\circ$ 时,大于 $\\frac{1}{2}$ 的个数的最大值是 2。\n答案是 C",
359
+ ),
360
+ (
361
+ "正方体 $A B C D-A_{1} B_{1} C_{1} D_{1}$ 中, $B B_{1}$ 与平面 $A C D_{1}$ 所成角的余弦值为 ( )\n从以下选项中选择:\n(A) $\\frac{\\sqrt{2}}{3}$\n(B) $\\frac{\\sqrt{3}}{3}$\n(C) $\\frac{2}{3}$\n(D) $\\frac{\\sqrt{6}}{3}$",
362
+ "设上下底面的中心分别为 $\\mathrm{O}_{1}, \\mathrm{O}$, 设正方体的棱长等于 1 , 则 $O_{1} O$ 与平面 $A C D_{1}$ 所成角就是 $B B_{1}$ 与平面 $A C D_{1}$ 所成角, 即 $\\angle O_{1} O D_{1}$, 直角三角形 $\\mathrm{OO}_{1} \\mathrm{D}_{1}$ 中, $\\cos \\angle \\mathrm{O}_{1} \\mathrm{OD}_{1}=\\frac{\\mathrm{O}_{1} \\mathrm{O}}{\\mathrm{OD}_{1}}=\\frac{\\frac{1}{\\sqrt{6}}}{2}=\\frac{\\sqrt{6}}{3}$. \n答案是 C",
363
+ ),
364
+ (
365
+ "设函数 $f(x)=\\left\\{\\begin{array}{ll}1+\\log _{2}(2-x), & x<1 \\ 2^{x-1}, & x \\geqslant 1,\\end{array}\\right.$ 则 $f(-2)+f\\left(\\log _{2} 12\\right)=$ ( )\n从以下选项中选择:\n(A) 3\n(B) 6\n(C) 9\n(D) 12",
366
+ "首先,我们可以根据定义计算 $f(-2)$ 和 $f(\\log_2 12)$:\n$f(-2)=1+\\log_2(2-(-2))=1+\\log_2 4=3$\n$f(\\log_2 12)=2^{\\log_2 12-1}=6$\n因此,$f(-2)+f(\\log_2 12)=3+6=9$。\n答案是 C",
367
+ ),
368
+ (
369
+ "已知函数 $f(x)=a x^{3}-3 x^{2}+1$, 若 $f(x)$ 存在唯一的零点 $x_{0}$, 且 $x_{0}>$ 0 , 则实数 $\\mathrm{a}$ 的取值范围是 ( )\n从以下选项中选择:\n(A) $(1,+\\infty)$\n(B) $(2,+\\infty)$\n(C) $(-\\infty,-1)$\n(D) $(-\\infty,-2)$",
370
+ "首先,我们可以通过求出函数的导函数 $f'(x)$ 来判断函数在 $x>0$ 区间内的单调性。在这里,我们求出导函数 $f'(x)$ 为 $f'(x)=3ax^2-6x$。\n然后,我们需要求出导函数 $f'(x)$ 的零点,以确定函数 $f(x)$ 在 $x>0$ 区间内的单调性。导函数 $f'(x)$ 的零点为 $x=0$ 和 $x=\\frac{2}{\\sqrt{a}}$。注意到 $x>0$,所以我们得到 $a<0$。此外,由于函数 $f(x)$ 在 $x=0$ 处的函数值为 $1$,因此不能有 $a=\\frac{4}{3}$。\n综上所述,当 $a$ 的取值范围为 $a<-\\frac{4}{3}$ 时,函数 $f(x)$ 在 $x>0$ 区间内是单调递减的,此时存在唯一的零点 $x_0$。因此,答案为 $(-\\infty,-2)$。\n答案是 D",
371
+ ),
372
+ (
373
+ "设 $\\left\\{a_{n}\\right\\}$ 是公差不为 0 的无穷等差数列, 则“ $\\left\\{a_{n}\\right\\}$ 为递增数列”是“存在正整数 $N_{0}$, 当 $n>N_{0}$ 时, $a_{n}>0$ ”的 ( )\n从以下选项中选择:\n(A) 充分而不必要条件\n(B) 必要而不充分条件\n(C) 充分必要条件\n(D) 既不充分也不必要条件",
374
+ "首先,我们可以通过举例来判断该条件是充分还是必要条件。如果一个数列递增,那么它的公差一定大于 0,也就是存在正整数 $N_{0}$,当 $n>N_{0}$ 时,$a_{n}>0$。因此,“ $\\left\\{a_{n}\\right\\}$ 为递增数列”是“存在正整数 $N_{0}$, 当 $n>N_{0}$ 时, $a_{n}>0$ ”的必要条件。\n接下来,我们需要判断是否充分。也就是说,如果存在正整数 $N_{0}$,当 $n>N_{0}$ 时,$a_{n}>0$,那么能否得出“ $\\left\\{a_{n}\\right\\}$ 为递增数列”这一结论。答案是肯定的。因为如果 $a_{n}>0$,那么 $a_{n+1}-a_{n}>0$,即公差大于 0,因此该数列是递增的。因此,该条件是充分条件。\n综上所述,选项为 (C) 充分必要条件。\n答案是 C",
375
+ ),
376
+ ]
377
+
378
+ return examples
grader.py ADDED
@@ -0,0 +1,395 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This logic is largely copied from the Hendrycks' MATH release (math_equivalence), and borrowed from:
3
+ - https://github.com/microsoft/ProphetNet/tree/master/CRITIC
4
+ - https://github.com/openai/prm800k
5
+ - https://github.com/microsoft/ToRA/blob/main/src/eval/grader.py
6
+ - https://github.com/deepseek-ai/DeepSeek-Math/blob/main/evaluation/eval/eval_utils.py
7
+ """
8
+
9
+ import re
10
+ import regex
11
+ import multiprocessing
12
+ from math import isclose
13
+ from typing import Union
14
+ from collections import defaultdict
15
+
16
+ from sympy import simplify, N
17
+ from sympy.parsing.sympy_parser import parse_expr
18
+ from sympy.parsing.latex import parse_latex
19
+ from latex2sympy2 import latex2sympy
20
+
21
+ # from .parser import choice_answer_clean, strip_string
22
+ # from parser import choice_answer_clean
23
+
24
+
25
+ def choice_answer_clean(pred: str):
26
+ pred = pred.strip("\n").rstrip(".").rstrip("/").strip(" ").lstrip(":")
27
+ # Clean the answer based on the dataset
28
+ tmp = re.findall(r"\b(A|B|C|D|E)\b", pred.upper())
29
+ if tmp:
30
+ pred = tmp
31
+ else:
32
+ pred = [pred.strip().strip(".")]
33
+ pred = pred[-1]
34
+ # Remove the period at the end, again!
35
+ pred = pred.rstrip(".").rstrip("/")
36
+ return pred
37
+
38
+
39
+ def parse_digits(num):
40
+ num = regex.sub(",", "", str(num))
41
+ try:
42
+ return float(num)
43
+ except:
44
+ if num.endswith("%"):
45
+ num = num[:-1]
46
+ if num.endswith("\\"):
47
+ num = num[:-1]
48
+ try:
49
+ return float(num) / 100
50
+ except:
51
+ pass
52
+ return None
53
+
54
+
55
+ def is_digit(num):
56
+ # paired with parse_digits
57
+ return parse_digits(num) is not None
58
+
59
+
60
+ def str_to_pmatrix(input_str):
61
+ input_str = input_str.strip()
62
+ matrix_str = re.findall(r"\{.*,.*\}", input_str)
63
+ pmatrix_list = []
64
+
65
+ for m in matrix_str:
66
+ m = m.strip("{}")
67
+ pmatrix = r"\begin{pmatrix}" + m.replace(",", "\\") + r"\end{pmatrix}"
68
+ pmatrix_list.append(pmatrix)
69
+
70
+ return ", ".join(pmatrix_list)
71
+
72
+
73
+ def math_equal(
74
+ prediction: Union[bool, float, str],
75
+ reference: Union[float, str],
76
+ include_percentage: bool = True,
77
+ is_close: bool = True,
78
+ timeout: bool = False,
79
+ ) -> bool:
80
+ """
81
+ Exact match of math if and only if:
82
+ 1. numerical equal: both can convert to float and are equal
83
+ 2. symbolic equal: both can convert to sympy expression and are equal
84
+ """
85
+ # print("Judge:", prediction, reference)
86
+ if prediction is None or reference is None:
87
+ return False
88
+ if str(prediction.strip().lower()) == str(reference.strip().lower()):
89
+ return True
90
+ if (
91
+ reference in ["A", "B", "C", "D", "E"]
92
+ and choice_answer_clean(prediction) == reference
93
+ ):
94
+ return True
95
+
96
+ try: # 1. numerical equal
97
+ if is_digit(prediction) and is_digit(reference):
98
+ prediction = parse_digits(prediction)
99
+ reference = parse_digits(reference)
100
+ # number questions
101
+ if include_percentage:
102
+ gt_result = [reference / 100, reference, reference * 100]
103
+ else:
104
+ gt_result = [reference]
105
+ for item in gt_result:
106
+ try:
107
+ if is_close:
108
+ if numeric_equal(prediction, item):
109
+ return True
110
+ else:
111
+ if item == prediction:
112
+ return True
113
+ except Exception:
114
+ continue
115
+ return False
116
+ except:
117
+ pass
118
+
119
+ if not prediction and prediction not in [0, False]:
120
+ return False
121
+
122
+ # 2. symbolic equal
123
+ reference = str(reference).strip()
124
+ prediction = str(prediction).strip()
125
+
126
+ ## pmatrix (amps)
127
+ if "pmatrix" in prediction and not "pmatrix" in reference:
128
+ reference = str_to_pmatrix(reference)
129
+
130
+ ## deal with [], (), {}
131
+ pred_str, ref_str = prediction, reference
132
+ if (
133
+ prediction.startswith("[")
134
+ and prediction.endswith("]")
135
+ and not reference.startswith("(")
136
+ ) or (
137
+ prediction.startswith("(")
138
+ and prediction.endswith(")")
139
+ and not reference.startswith("[")
140
+ ):
141
+ pred_str = pred_str.strip("[]()")
142
+ ref_str = ref_str.strip("[]()")
143
+ for s in ["{", "}", "(", ")"]:
144
+ ref_str = ref_str.replace(s, "")
145
+ pred_str = pred_str.replace(s, "")
146
+ if pred_str.lower() == ref_str.lower():
147
+ return True
148
+
149
+ ## [a, b] vs. [c, d], return a==c and b==d
150
+ if (
151
+ regex.match(r"(\(|\[).+(\)|\])", prediction) is not None
152
+ and regex.match(r"(\(|\[).+(\)|\])", reference) is not None
153
+ ):
154
+ pred_parts = prediction[1:-1].split(",")
155
+ ref_parts = reference[1:-1].split(",")
156
+ if len(pred_parts) == len(ref_parts):
157
+ if all(
158
+ [
159
+ math_equal(
160
+ pred_parts[i], ref_parts[i], include_percentage, is_close
161
+ )
162
+ for i in range(len(pred_parts))
163
+ ]
164
+ ):
165
+ return True
166
+ if (
167
+ (
168
+ prediction.startswith("\\begin{pmatrix}")
169
+ or prediction.startswith("\\begin{bmatrix}")
170
+ )
171
+ and (
172
+ prediction.endswith("\\end{pmatrix}")
173
+ or prediction.endswith("\\end{bmatrix}")
174
+ )
175
+ and (
176
+ reference.startswith("\\begin{pmatrix}")
177
+ or reference.startswith("\\begin{bmatrix}")
178
+ )
179
+ and (
180
+ reference.endswith("\\end{pmatrix}") or reference.endswith("\\end{bmatrix}")
181
+ )
182
+ ):
183
+ pred_lines = [
184
+ line.strip()
185
+ for line in prediction[
186
+ len("\\begin{pmatrix}") : -len("\\end{pmatrix}")
187
+ ].split("\\\\")
188
+ if line.strip()
189
+ ]
190
+ ref_lines = [
191
+ line.strip()
192
+ for line in reference[
193
+ len("\\begin{pmatrix}") : -len("\\end{pmatrix}")
194
+ ].split("\\\\")
195
+ if line.strip()
196
+ ]
197
+ matched = True
198
+ if len(pred_lines) == len(ref_lines):
199
+ for pred_line, ref_line in zip(pred_lines, ref_lines):
200
+ pred_parts = pred_line.split("&")
201
+ ref_parts = ref_line.split("&")
202
+ if len(pred_parts) == len(ref_parts):
203
+ if not all(
204
+ [
205
+ math_equal(
206
+ pred_parts[i],
207
+ ref_parts[i],
208
+ include_percentage,
209
+ is_close,
210
+ )
211
+ for i in range(len(pred_parts))
212
+ ]
213
+ ):
214
+ matched = False
215
+ break
216
+ else:
217
+ matched = False
218
+ if not matched:
219
+ break
220
+ else:
221
+ matched = False
222
+ if matched:
223
+ return True
224
+
225
+ if prediction.count("=") == 1 and reference.count("=") == 1:
226
+ pred = prediction.split("=")
227
+ pred = f"{pred[0].strip()} - ({pred[1].strip()})"
228
+ ref = reference.split("=")
229
+ ref = f"{ref[0].strip()} - ({ref[1].strip()})"
230
+ if symbolic_equal(pred, ref) or symbolic_equal(f"-({pred})", ref):
231
+ return True
232
+ elif (
233
+ prediction.count("=") == 1
234
+ and len(prediction.split("=")[0].strip()) <= 2
235
+ and "=" not in reference
236
+ ):
237
+ if math_equal(
238
+ prediction.split("=")[1], reference, include_percentage, is_close
239
+ ):
240
+ return True
241
+ elif (
242
+ reference.count("=") == 1
243
+ and len(reference.split("=")[0].strip()) <= 2
244
+ and "=" not in prediction
245
+ ):
246
+ if math_equal(
247
+ prediction, reference.split("=")[1], include_percentage, is_close
248
+ ):
249
+ return True
250
+
251
+ # symbolic equal with sympy
252
+ if timeout:
253
+ if call_with_timeout(symbolic_equal_process, prediction, reference):
254
+ return True
255
+ else:
256
+ if symbolic_equal(prediction, reference):
257
+ return True
258
+
259
+ return False
260
+
261
+
262
+ def math_equal_process(param):
263
+ return math_equal(param[-2], param[-1])
264
+
265
+
266
+ def numeric_equal(prediction: float, reference: float):
267
+ # Note that relative tolerance has significant impact
268
+ # on the result of the synthesized GSM-Hard dataset
269
+ # if reference.is_integer():
270
+ # return isclose(reference, round(prediction), abs_tol=1e-4)
271
+ # else:
272
+ # prediction = round(prediction, len(str(reference).split(".")[-1]))
273
+ return isclose(reference, prediction, rel_tol=1e-4)
274
+
275
+
276
+ def symbolic_equal(a, b):
277
+ def _parse(s):
278
+ for f in [parse_latex, parse_expr, latex2sympy]:
279
+ try:
280
+ return f(s.replace("\\\\", "\\"))
281
+ except:
282
+ try:
283
+ return f(s)
284
+ except:
285
+ pass
286
+ return s
287
+
288
+ a = _parse(a)
289
+ b = _parse(b)
290
+
291
+ # direct equal
292
+ try:
293
+ if str(a) == str(b) or a == b:
294
+ return True
295
+ except:
296
+ pass
297
+
298
+ # simplify equal
299
+ try:
300
+ if a.equals(b) or simplify(a - b) == 0:
301
+ return True
302
+ except:
303
+ pass
304
+
305
+ # equation equal
306
+ try:
307
+ if (abs(a.lhs - a.rhs)).equals(abs(b.lhs - b.rhs)):
308
+ return True
309
+ except:
310
+ pass
311
+
312
+ try:
313
+ if numeric_equal(float(N(a)), float(N(b))):
314
+ return True
315
+ except:
316
+ pass
317
+
318
+ # matrix
319
+ try:
320
+ # if a and b are matrix
321
+ if a.shape == b.shape:
322
+ _a = a.applyfunc(lambda x: round(x, 3))
323
+ _b = b.applyfunc(lambda x: round(x, 3))
324
+ if _a.equals(_b):
325
+ return True
326
+ except:
327
+ pass
328
+
329
+ return False
330
+
331
+
332
+ def symbolic_equal_process(a, b, output_queue):
333
+ result = symbolic_equal(a, b)
334
+ output_queue.put(result)
335
+
336
+
337
+ def call_with_timeout(func, *args, timeout=1, **kwargs):
338
+ output_queue = multiprocessing.Queue()
339
+ process_args = args + (output_queue,)
340
+ process = multiprocessing.Process(target=func, args=process_args, kwargs=kwargs)
341
+ process.start()
342
+ process.join(timeout)
343
+
344
+ if process.is_alive():
345
+ process.terminate()
346
+ process.join()
347
+ return False
348
+
349
+ return output_queue.get()
350
+
351
+ def _test_math_equal():
352
+ # print(math_equal("0.0833333333333333", "\\frac{1}{12}"))
353
+ # print(math_equal("(1,4.5)", "(1,\\frac{9}{2})"))
354
+ # print(math_equal("\\frac{x}{7}+\\frac{2}{7}", "\\frac{x+2}{7}", timeout=True))
355
+ # print(math_equal("\\sec^2(y)", "\\tan^2(y)+1", timeout=True))
356
+ # print(math_equal("\\begin{pmatrix}-\\frac{7}{4}&-2\\\\4&\\frac{1}{4}\\end{pmatrix}", "(\\begin{pmatrix}-\\frac{7}{4}&-2\\\\4&\\frac{1}{4}\\\\\\end{pmatrix})", timeout=True))
357
+
358
+ # pred = '\\begin{pmatrix}\\frac{1}{3x^{2/3}}&0&0\\\\0&1&0\\\\-\\sin(x)&0&0\\end{pmatrix}'
359
+ # gt = '(\\begin{pmatrix}\\frac{1}{3\\sqrt[3]{x}^2}&0&0\\\\0&1&0\\\\-\\sin(x)&0&0\\\\\\end{pmatrix})'
360
+
361
+ # pred= '-\\frac{8x^2}{9(x^2-2)^{5/3}}+\\frac{2}{3(x^2-2)^{2/3}}'
362
+ # gt= '-\\frac{2(x^2+6)}{9(x^2-2)\\sqrt[3]{x^2-2}^2}'
363
+
364
+ # pred = '-34x-45y+20z-100=0'
365
+ # gt = '34x+45y-20z+100=0'
366
+
367
+ # pred = '\\frac{100}{3}'
368
+ # gt = '33.3'
369
+
370
+ # pred = '\\begin{pmatrix}0.290243531202435\\\\0.196008371385084\\\\-0.186381278538813\\end{pmatrix}'
371
+ # gt = '(\\begin{pmatrix}0.29\\\\0.196\\\\-0.186\\\\\\end{pmatrix})'
372
+
373
+ # pred = '\\frac{\\sqrt{\\sqrt{11}+\\sqrt{194}}}{2\\sqrt{33}+15}'
374
+ # gt = '\\frac{\\sqrt{\\sqrt{11}+\\sqrt{194}}}{15+2\\sqrt{33}}'
375
+
376
+ # pred = '(+5)(b+2)'
377
+ # gt = '(a+5)(b+2)'
378
+
379
+ # pred = '\\frac{1+\\sqrt{5}}{2}'
380
+ # gt = '2'
381
+
382
+ # pred = '\\frac{34}{16}+\\frac{\\sqrt{1358}}{16}', gt = '4'
383
+ # pred = '1', gt = '1\\\\sqrt{19}'
384
+
385
+ # pred = "(0.6,2.6667]"
386
+ # gt = "(\\frac{3}{5},\\frac{8}{3}]"
387
+
388
+ gt = "x+2n+1"
389
+ pred = "x+1"
390
+
391
+ print(math_equal(pred, gt, timeout=True))
392
+
393
+
394
+ if __name__ == "__main__":
395
+ _test_math_equal()
latex2sympy/.coveragerc ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # .coveragerc to control coverage.py
2
+ [run]
3
+ branch = True
4
+ include =
5
+ latex2sympy.py
6
+ omit =
7
+ sandbox/*
8
+ gen/*
9
+ asciimath_printer.py
10
+ setup.py
11
+ __init__.py
12
+
13
+ [report]
14
+ # Regexes for lines to exclude from consideration
15
+ exclude_lines =
16
+ # Have to re-enable the standard pragma
17
+ pragma: no cover
18
+
19
+ # Don't complain about missing debug-only code:
20
+ def __repr__
21
+ if self\.debug
22
+
23
+ # Don't complain if tests don't hit defensive assertion code:
24
+ raise AssertionError
25
+ raise NotImplementedError
26
+
27
+ # Don't complain if non-runnable code isn't run:
28
+ if 0:
29
+ if __name__ == .__main__.:
30
+
31
+ ignore_errors = True
latex2sympy/.gitignore ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ .antlr
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ pip-wheel-metadata/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+
63
+ # Flask stuff:
64
+ instance/
65
+ .webassets-cache
66
+
67
+ # Scrapy stuff:
68
+ .scrapy
69
+
70
+ # Sphinx documentation
71
+ docs/_build/
72
+
73
+ # PyBuilder
74
+ target/
75
+
76
+ # Jupyter Notebook
77
+ .ipynb_checkpoints
78
+
79
+ # IPython
80
+ profile_default/
81
+ ipython_config.py
82
+
83
+ # pyenv
84
+ .python-version
85
+
86
+ # pipenv
87
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
88
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
89
+ # having no cross-platform support, pipenv may install dependencies that don’t work, or not
90
+ # install all needed dependencies.
91
+ #Pipfile.lock
92
+
93
+ # celery beat schedule file
94
+ celerybeat-schedule
95
+
96
+ # SageMath parsed files
97
+ *.sage.py
98
+
99
+ # Environments
100
+ .env
101
+ .venv
102
+ env/
103
+ venv/
104
+ ENV/
105
+ env.bak/
106
+ venv.bak/
107
+
108
+ # Spyder project settings
109
+ .spyderproject
110
+ .spyproject
111
+
112
+ # Rope project settings
113
+ .ropeproject
114
+
115
+ # mkdocs documentation
116
+ /site
117
+
118
+ # mypy
119
+ .mypy_cache/
120
+ .dmypy.json
121
+ dmypy.json
122
+
123
+ # Pyre type checker
124
+ .pyre/
125
+
126
+ # Azure Functions artifacts
127
+ bin
128
+ obj
129
+ appsettings.json
130
+ local.settings.json
131
+ .python_packages
132
+ stemgen-solution-engine.zip
latex2sympy/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright 2016, latex2sympy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
latex2sympy/PS.g4 ADDED
@@ -0,0 +1,638 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ grammar PS;
2
+
3
+ options {
4
+ language=Python2;
5
+ }
6
+
7
+ WS: [ \t\r\n]+ -> skip;
8
+ DOLLAR_SIGN: '\\$' -> skip;
9
+
10
+ ADD: '+';
11
+ SUB: '-';
12
+ MUL: '*';
13
+ DIV: '/' | '\\over';
14
+
15
+ L_PAREN: '(';
16
+ R_PAREN: ')';
17
+ L_GROUP: '\\lgroup';
18
+ R_GROUP: '\\rgroup';
19
+ L_BRACE: '{';
20
+ R_BRACE: '}';
21
+ L_BRACE_VISUAL: '\\{';
22
+ R_BRACE_VISUAL: '\\}';
23
+ L_BRACE_CMD: '\\lbrace';
24
+ R_BRACE_CMD: '\\rbrace';
25
+ L_BRACKET: '[';
26
+ R_BRACKET: ']';
27
+ L_BRACK: '\\lbrack';
28
+ R_BRACK: '\\rbrack';
29
+
30
+ BAR: '|';
31
+ L_VERT: '\\lvert';
32
+ R_VERT: '\\rvert';
33
+ VERT: '\\vert';
34
+
35
+ NORM: '\\|';
36
+
37
+ L_FLOOR: '\\lfloor';
38
+ R_FLOOR: '\\rfloor';
39
+ LL_CORNER: '\\llcorner';
40
+ LR_CORNER: '\\lrcorner';
41
+
42
+ L_CEIL: '\\lceil';
43
+ R_CEIL: '\\rceil';
44
+ UL_CORNER: '\\ulcorner';
45
+ UR_CORNER: '\\urcorner';
46
+
47
+ L_LEFT: '\\left';
48
+ R_RIGHT: '\\right';
49
+ ML_LEFT: '\\mleft';
50
+ MR_RIGHT: '\\mright';
51
+
52
+ //functions
53
+ FUNC_LIM: '\\lim';
54
+ LIM_APPROACH_SYM: '\\to' | '\\rightarrow' | '\\Rightarrow' | '\\longrightarrow' | '\\Longrightarrow';
55
+ FUNC_INT: '\\int';
56
+ FUNC_SUM: '\\sum';
57
+ FUNC_PROD: '\\prod';
58
+
59
+ FUNC_LOG: '\\log';
60
+ FUNC_LN: '\\ln';
61
+ FUNC_EXP: '\\exp';
62
+ FUNC_SIN: '\\sin';
63
+ FUNC_COS: '\\cos';
64
+ FUNC_TAN: '\\tan';
65
+ FUNC_CSC: '\\csc';
66
+ FUNC_SEC: '\\sec';
67
+ FUNC_COT: '\\cot';
68
+
69
+ FUNC_ARCSIN: '\\arcsin';
70
+ FUNC_ARCCOS: '\\arccos';
71
+ FUNC_ARCTAN: '\\arctan';
72
+ FUNC_ARCCSC: '\\arccsc';
73
+ FUNC_ARCSEC: '\\arcsec';
74
+ FUNC_ARCCOT: '\\arccot';
75
+
76
+ FUNC_SINH: '\\sinh';
77
+ FUNC_COSH: '\\cosh';
78
+ FUNC_TANH: '\\tanh';
79
+ FUNC_ARSINH: '\\arsinh';
80
+ FUNC_ARCOSH: '\\arcosh';
81
+ FUNC_ARTANH: '\\artanh';
82
+ FUNC_ARCSINH: '\\arcsinh';
83
+ FUNC_ARCCOSH: '\\arccosh';
84
+ FUNC_ARCTANH: '\\arctanh';
85
+
86
+ FUNC_ARSINH_NAME: 'arsinh';
87
+ FUNC_ARCSINH_NAME: 'arcsinh';
88
+ FUNC_ARCOSH_NAME: 'arcosh';
89
+ FUNC_ARCCOSH_NAME: 'arccosh';
90
+ FUNC_ARTANH_NAME: 'artanh';
91
+ FUNC_ARCTANH_NAME: 'arctanh';
92
+ FUNC_GCD_NAME: 'gcd';
93
+ FUNC_LCM_NAME: 'lcm';
94
+ FUNC_FLOOR_NAME: 'floor';
95
+ FUNC_CEIL_NAME: 'ceil';
96
+
97
+ FUNC_SQRT: '\\sqrt';
98
+ FUNC_GCD: '\\gcd';
99
+ FUNC_LCM: '\\lcm';
100
+ FUNC_FLOOR: '\\floor';
101
+ FUNC_CEIL: '\\ceil';
102
+ FUNC_MAX: '\\max';
103
+ FUNC_MIN: '\\min';
104
+
105
+ FUNC_DET: '\\det';
106
+
107
+ FUNC_EYE_NAME: 'eye';
108
+ FUNC_ZEROS_NAME: 'zeros';
109
+ FUNC_ONES_NAME: 'ones';
110
+ FUNC_COLS_NAME: 'cols';
111
+ FUNC_ROWS_NAME: 'rows';
112
+ FUNC_DIAG_NAME: 'diag';
113
+ FUNC_NORM_NAME: 'norm';
114
+ FUNC_RANK_NAME: 'rank';
115
+ FUNC_TRACE_NAME: 'trace' | 'tr';
116
+ FUNC_RREF_NAME: 'rref';
117
+ FUNC_HSTACK_NAME: 'hstack';
118
+ FUNC_VSTACK_NAME: 'vstack';
119
+ FUNC_ORTHOGONALIZE_NAME: 'orth' | 'ortho' | 'orthogonal' | 'orthogonalize';
120
+ FUNC_NULLSPACE_NAME: 'nullspace';
121
+ FUNC_DIAGONALIZE_NAME: 'eig' | 'eigen' | 'diagonalize';
122
+ FUNC_EIGENVALS_NAME: 'eigenvals' | 'eigenvalues';
123
+ FUNC_EIGENVECTORS_NAME: 'eigenvects' | 'eigenvectors';
124
+ FUNC_SVD_NAME: 'svd' | 'SVD';
125
+
126
+ //commands
127
+ CMD_TIMES: '\\times';
128
+ CMD_CDOT: '\\cdot';
129
+ CMD_DIV: '\\div';
130
+ CMD_FRAC: '\\frac';
131
+ CMD_BINOM: '\\binom' | '\\tbinom' | '\\dbinom';
132
+ CMD_CHOOSE: '\\choose';
133
+ CMD_MOD: '\\mod';
134
+
135
+ CMD_MATHIT: '\\mathit';
136
+
137
+ CMD_OPERATORNAME: '\\operatorname';
138
+
139
+ //matrix test
140
+ MATRIX_TYPE_MATRIX: 'matrix';
141
+ MATRIX_TYPE_PMATRIX: 'pmatrix';
142
+ MATRIX_TYPE_BMATRIX: 'bmatrix';
143
+ MATRIX_TYPE_DET: 'vmatrix';
144
+ MATRIX_TYPES: MATRIX_TYPE_MATRIX | MATRIX_TYPE_PMATRIX | MATRIX_TYPE_BMATRIX;
145
+ CMD_MATRIX_START: '\\begin' L_BRACE MATRIX_TYPES R_BRACE;
146
+ CMD_MATRIX_END: '\\end' L_BRACE MATRIX_TYPES R_BRACE;
147
+ CMD_DET_START: '\\begin' L_BRACE MATRIX_TYPE_DET R_BRACE;
148
+ CMD_DET_END: '\\end' L_BRACE MATRIX_TYPE_DET R_BRACE;
149
+ MATRIX_DEL_COL: '&';
150
+ MATRIX_DEL_ROW: '\\\\';
151
+
152
+ UNDERSCORE: '_';
153
+ CARET: '^';
154
+ COLON: ':';
155
+ SEMICOLON: ';';
156
+ COMMA: ',';
157
+ PERIOD: '.';
158
+
159
+ fragment WS_CHAR: [ \t\r\n];
160
+ DIFFERENTIAL: 'd' WS_CHAR*? ([a-zA-Z] | '\\' [a-zA-Z]+);
161
+
162
+ EXP_E: 'e' | '\\exponentialE';
163
+ E_NOTATION_E: 'E';
164
+ LETTER_NO_E: [a-df-zA-DF-Z]; // exclude e for exponential function and e notation
165
+ fragment LETTER: [a-zA-Z];
166
+ fragment DIGIT: [0-9];
167
+
168
+ MATRIX_XRIGHTARROW: '\\xrightarrow' | '\\xRightarrow';
169
+ TRANSFORM_EXCHANGE: '<->' | '<=>' | '\\leftrightarrow' | '\\Leftrightarrow';
170
+
171
+ NUMBER:
172
+ DIGIT+ (COMMA DIGIT DIGIT DIGIT)*
173
+ | DIGIT* (COMMA DIGIT DIGIT DIGIT)* PERIOD DIGIT+;
174
+
175
+ E_NOTATION: NUMBER E_NOTATION_E (SUB | ADD)? DIGIT+;
176
+
177
+ IN: '\\in';
178
+ ASSIGNMENT: '=';
179
+ EQUAL: '==' | '\\equiv';
180
+ LT: '<';
181
+ LTE: '\\leq' | '\\le' | '\\leqslant';
182
+ GT: '>';
183
+ GTE: '\\geq' | '\\ge' | '\\geqslant';
184
+ UNEQUAL: '!=' | '!==' | '\\ne' | '\\neq' | '\\not\\equiv';
185
+
186
+ BANG: '!';
187
+
188
+ fragment PERCENT_SIGN: '\\%';
189
+ PERCENT_NUMBER: NUMBER PERCENT_SIGN;
190
+
191
+ //Excludes some letters for use as e.g. constants in SYMBOL
192
+ fragment GREEK_LETTER:
193
+ '\\char"000391' | //Alpha
194
+ '\\alpha' |
195
+ '\\char"000392' | //Beta
196
+ '\\beta' |
197
+ '\\Gamma' |
198
+ '\\gamma' |
199
+ '\\Delta' |
200
+ '\\delta' |
201
+ '\\char"000190' | //Epsilon
202
+ '\\epsilon' |
203
+ '\\varepsilon' |
204
+ '\\char"000396' | //Zeta
205
+ '\\zeta' |
206
+ '\\char"000397' | //Eta
207
+ '\\eta' |
208
+ '\\Theta' |
209
+ '\\theta' |
210
+ '\\vartheta' |
211
+ '\\char"000399' | //Iota
212
+ '\\iota' |
213
+ '\\char"00039A' | //Kappa
214
+ '\\kappa' |
215
+ '\\Lambda' |
216
+ '\\lambda' |
217
+ '\\char"00039C' | //Mu
218
+ '\\mu' |
219
+ '\\char"00039D' | //Nu
220
+ '\\nu' |
221
+ '\\Xi' |
222
+ '\\xi' |
223
+ '\\char"00039F' | //Omicron
224
+ '\\omicron' |
225
+ '\\Pi' |
226
+ '\\varpi' |
227
+ '\\char"0003A1' | //Rho
228
+ '\\rho' |
229
+ '\\varrho' |
230
+ '\\Sigma' |
231
+ '\\sigma' |
232
+ '\\varsigma' |
233
+ '\\char"0003A4' | //Tau
234
+ '\\tau' |
235
+ '\\Upsilon' |
236
+ '\\upsilon' |
237
+ '\\Phi' |
238
+ '\\phi' |
239
+ '\\varphi' |
240
+ '\\char"0003A7' | //Chi
241
+ '\\chi' |
242
+ '\\Psi' |
243
+ '\\psi' |
244
+ '\\Omega' |
245
+ '\\omega';
246
+
247
+ GREEK_CMD: GREEK_LETTER [ ]?;
248
+
249
+ fragment OTHER_SYMBOL:
250
+ '\\Bbbk' |
251
+ '\\wp' |
252
+ '\\nabla' |
253
+ '\\bigstar' |
254
+ '\\angle' |
255
+ '\\nexists' |
256
+ '\\diagdown' |
257
+ '\\measuredangle' |
258
+ '\\eth' |
259
+ '\\emptyset' |
260
+ '\\diagup' |
261
+ '\\sphericalangle' |
262
+ '\\clubsuit' |
263
+ '\\varnothing' |
264
+ '\\Diamond' |
265
+ '\\complement' |
266
+ '\\diamondsuit' |
267
+ '\\imath' |
268
+ '\\Finv' |
269
+ '\\triangledown' |
270
+ '\\heartsuit' |
271
+ '\\jmath' |
272
+ '\\Game' |
273
+ '\\triangle' |
274
+ '\\spadesuit' |
275
+ '\\ell' |
276
+ '\\hbar' |
277
+ '\\vartriangle' |
278
+ '\\hslash' |
279
+ '\\blacklozenge' |
280
+ '\\lozenge' |
281
+ '\\blacksquare' |
282
+ '\\mho' |
283
+ '\\blacktriangle' |
284
+ '\\sharp' |
285
+ '\\prime' |
286
+ '\\Im' |
287
+ '\\flat' |
288
+ '\\square' |
289
+ '\\backprime' |
290
+ '\\Re' |
291
+ '\\natural' |
292
+ '\\surd' |
293
+ '\\circledS';
294
+ OTHER_SYMBOL_CMD: OTHER_SYMBOL [ ]?;
295
+
296
+ fragment PI: '\\pi';
297
+ fragment INFTY_CMD: '\\infty';
298
+ fragment PARTIAL_CMD: '\\partial';
299
+ fragment INFTY: INFTY_CMD | DOLLAR_SIGN INFTY_CMD | INFTY_CMD PERCENT_SIGN;
300
+ fragment EMPTYSET: '\\emptyset';
301
+ SYMBOL: PI | PARTIAL_CMD | INFTY | EMPTYSET;
302
+
303
+ fragment VARIABLE_CMD: '\\variable';
304
+ fragment VARIABLE_SYMBOL: (GREEK_CMD | OTHER_SYMBOL_CMD | LETTER | DIGIT)+ (UNDERSCORE ((L_BRACE (GREEK_CMD | OTHER_SYMBOL_CMD | LETTER | DIGIT | COMMA)+ R_BRACE) | (GREEK_CMD | OTHER_SYMBOL_CMD | LETTER | DIGIT)))?;
305
+ VARIABLE: VARIABLE_CMD L_BRACE VARIABLE_SYMBOL R_BRACE PERCENT_SIGN?;
306
+
307
+ //collection of accents
308
+ accent_symbol:
309
+ '\\acute' |
310
+ '\\bar' |
311
+ '\\overline' |
312
+ '\\breve' |
313
+ '\\check' |
314
+ '\\widecheck' |
315
+ '\\dot' |
316
+ '\\ddot' |
317
+ '\\grave' |
318
+ '\\hat' |
319
+ '\\tilde' |
320
+ '\\widetilde' |
321
+ '\\vec' |
322
+ '\\overrightarrow' |
323
+ '\\bm' |
324
+ '\\boldsymbol' |
325
+ '\\text' |
326
+ '\\textit' |
327
+ '\\mathbb' |
328
+ '\\mathbin' |
329
+ '\\mathbf' |
330
+ '\\mathcal' |
331
+ '\\mathclap' |
332
+ '\\mathclose' |
333
+ '\\mathellipsis' |
334
+ '\\mathfrak' |
335
+ '\\mathinner' |
336
+ '\\mathit' |
337
+ '\\mathnormal' |
338
+ '\\mathop' |
339
+ '\\mathopen' |
340
+ '\\mathord' |
341
+ '\\mathpunct' |
342
+ '\\mathrel' |
343
+ '\\mathring' |
344
+ '\\mathrlap' |
345
+ '\\mathrm' |
346
+ '\\mathscr' |
347
+ '\\mathsf' |
348
+ '\\mathsterling' |
349
+ '\\mathtt';
350
+
351
+ math: relation | relation_list;
352
+
353
+ transpose: '^T' | '^{T}' | '^{\\top}' | '\'';
354
+
355
+ transform_atom: LETTER_NO_E UNDERSCORE (NUMBER | L_BRACE NUMBER R_BRACE);
356
+ transform_scale: (expr | group | ADD | SUB) transform_atom;
357
+ transform_swap: transform_atom TRANSFORM_EXCHANGE transform_atom;
358
+ transform_assignment: transform_atom transform_scale;
359
+ elementary_transform: transform_assignment | transform_scale | transform_swap;
360
+ elementary_transforms: elementary_transform (COMMA elementary_transform)*;
361
+
362
+ matrix:
363
+ CMD_MATRIX_START
364
+ matrix_row (MATRIX_DEL_ROW matrix_row)* MATRIX_DEL_ROW?
365
+ CMD_MATRIX_END
366
+ (MATRIX_XRIGHTARROW (L_BRACKET elementary_transforms R_BRACKET)? L_BRACE elementary_transforms R_BRACE)?;
367
+
368
+ det:
369
+ CMD_DET_START
370
+ matrix_row (MATRIX_DEL_ROW matrix_row)* MATRIX_DEL_ROW?
371
+ CMD_DET_END;
372
+
373
+ matrix_row:
374
+ expr (MATRIX_DEL_COL expr)*;
375
+
376
+ relation:
377
+ relation (IN | ASSIGNMENT | EQUAL | LT | LTE | GT | GTE | UNEQUAL) relation
378
+ | expr;
379
+
380
+ relation_list:
381
+ relation_list_content
382
+ | L_BRACKET relation_list_content R_BRACKET
383
+ | L_BRACE relation_list_content R_BRACE
384
+ | L_BRACE_VISUAL relation_list_content R_BRACE_VISUAL
385
+ | L_LEFT L_BRACKET relation_list_content R_RIGHT R_BRACKET
386
+ | L_LEFT L_BRACE_VISUAL relation_list_content R_RIGHT R_BRACE_VISUAL
387
+ | ML_LEFT L_BRACKET relation_list_content MR_RIGHT R_BRACKET
388
+ | ML_LEFT L_BRACE_VISUAL relation_list_content MR_RIGHT R_BRACE_VISUAL;
389
+
390
+ relation_list_content:
391
+ relation COMMA relation (COMMA relation)*
392
+ | relation SEMICOLON relation (SEMICOLON relation)*;
393
+
394
+ equality:
395
+ expr (EQUAL | ASSIGNMENT) expr;
396
+
397
+ expr: additive;
398
+
399
+ additive:
400
+ additive (ADD | SUB) additive
401
+ | mp;
402
+
403
+ // mult part
404
+ mp:
405
+ mp (MUL | CMD_TIMES | CMD_CDOT | DIV | CMD_DIV | COLON | CMD_MOD) mp
406
+ | unary;
407
+
408
+ mp_nofunc:
409
+ mp_nofunc (MUL | CMD_TIMES | CMD_CDOT | DIV | CMD_DIV | COLON | CMD_MOD) mp_nofunc
410
+ | unary_nofunc;
411
+
412
+ unary:
413
+ (ADD | SUB) unary
414
+ | postfix+;
415
+
416
+ unary_nofunc:
417
+ (ADD | SUB) unary_nofunc
418
+ | postfix postfix_nofunc*;
419
+
420
+ postfix: exp postfix_op*;
421
+ postfix_nofunc: exp_nofunc postfix_op*;
422
+ postfix_op: BANG | eval_at | transpose;
423
+
424
+ eval_at:
425
+ BAR (eval_at_sup | eval_at_sub | eval_at_sup eval_at_sub);
426
+
427
+ eval_at_sub:
428
+ UNDERSCORE L_BRACE
429
+ (expr | equality)
430
+ R_BRACE;
431
+
432
+ eval_at_sup:
433
+ CARET L_BRACE
434
+ (expr | equality)
435
+ R_BRACE;
436
+
437
+ exp:
438
+ exp CARET (atom | L_BRACE expr R_BRACE) subexpr?
439
+ | comp;
440
+
441
+ exp_nofunc:
442
+ exp_nofunc CARET (atom | L_BRACE expr R_BRACE) subexpr?
443
+ | comp_nofunc;
444
+
445
+ comp:
446
+ group
447
+ | norm_group
448
+ | abs_group
449
+ | floor_group
450
+ | ceil_group
451
+ | func
452
+ | atom
453
+ | frac
454
+ | binom
455
+ | matrix
456
+ | det;
457
+
458
+ comp_nofunc:
459
+ group
460
+ | norm_group
461
+ | abs_group
462
+ | floor_group
463
+ | ceil_group
464
+ | atom
465
+ | frac
466
+ | binom
467
+ | matrix
468
+ | det;
469
+
470
+ group:
471
+ L_PAREN expr R_PAREN
472
+ | L_GROUP expr R_GROUP
473
+ | L_BRACE expr R_BRACE
474
+ | L_BRACE_VISUAL expr R_BRACE_VISUAL
475
+ | L_BRACE_CMD expr R_BRACE_CMD
476
+ | L_BRACKET expr R_BRACKET
477
+ | L_BRACK expr R_BRACK
478
+ | L_LEFT L_PAREN expr R_RIGHT R_PAREN
479
+ | L_LEFT L_GROUP expr R_RIGHT R_GROUP
480
+ | L_LEFT L_BRACE expr R_RIGHT R_BRACE
481
+ | L_LEFT L_BRACE_VISUAL expr R_RIGHT R_BRACE_VISUAL
482
+ | L_LEFT L_BRACE_CMD expr R_RIGHT R_BRACE_CMD
483
+ | L_LEFT L_BRACKET expr R_RIGHT R_BRACKET
484
+ | L_LEFT L_BRACK expr R_RIGHT R_BRACK
485
+ | ML_LEFT L_PAREN expr MR_RIGHT R_PAREN
486
+ | ML_LEFT L_GROUP expr MR_RIGHT R_GROUP
487
+ | ML_LEFT L_BRACE expr MR_RIGHT R_BRACE
488
+ | ML_LEFT L_BRACE_VISUAL expr MR_RIGHT R_BRACE_VISUAL
489
+ | ML_LEFT L_BRACE_CMD expr MR_RIGHT R_BRACE_CMD
490
+ | ML_LEFT L_BRACKET expr MR_RIGHT R_BRACKET
491
+ | ML_LEFT L_BRACK expr MR_RIGHT R_BRACK;
492
+
493
+
494
+ norm_group:
495
+ NORM expr NORM
496
+ | L_LEFT NORM expr R_RIGHT NORM
497
+ | ML_LEFT NORM expr MR_RIGHT NORM;
498
+
499
+
500
+ abs_group:
501
+ BAR expr BAR
502
+ | L_VERT expr R_VERT
503
+ | VERT expr VERT
504
+ | L_LEFT BAR expr R_RIGHT BAR
505
+ | L_LEFT L_VERT expr R_RIGHT R_VERT
506
+ | L_LEFT VERT expr R_RIGHT VERT
507
+ | ML_LEFT BAR expr MR_RIGHT BAR
508
+ | ML_LEFT L_VERT expr MR_RIGHT R_VERT
509
+ | ML_LEFT VERT expr MR_RIGHT VERT;
510
+
511
+
512
+ floor_group:
513
+ L_FLOOR expr R_FLOOR
514
+ | LL_CORNER expr LR_CORNER
515
+ | L_LEFT L_FLOOR expr R_RIGHT R_FLOOR
516
+ | L_LEFT LL_CORNER expr R_RIGHT LR_CORNER
517
+ | ML_LEFT L_FLOOR expr MR_RIGHT R_FLOOR
518
+ | ML_LEFT LL_CORNER expr MR_RIGHT LR_CORNER;
519
+
520
+
521
+ ceil_group:
522
+ L_CEIL expr R_CEIL
523
+ | UL_CORNER expr UR_CORNER
524
+ | L_LEFT L_CEIL expr R_RIGHT R_CEIL
525
+ | L_LEFT UL_CORNER expr R_RIGHT UR_CORNER
526
+ | ML_LEFT L_CEIL expr MR_RIGHT R_CEIL
527
+ | ML_LEFT UL_CORNER expr MR_RIGHT UR_CORNER;
528
+
529
+
530
+ //indicate an accent
531
+ accent:
532
+ accent_symbol
533
+ L_BRACE base=expr R_BRACE;
534
+
535
+ atom_expr_no_supexpr: (LETTER_NO_E | GREEK_CMD | OTHER_SYMBOL_CMD | accent) subexpr?;
536
+ atom_expr: (LETTER_NO_E | GREEK_CMD | OTHER_SYMBOL_CMD | accent) (supexpr subexpr | subexpr supexpr | subexpr | supexpr)?;
537
+ atom: atom_expr | SYMBOL | NUMBER | PERCENT_NUMBER | E_NOTATION | DIFFERENTIAL | mathit | VARIABLE;
538
+
539
+ mathit: CMD_MATHIT L_BRACE mathit_text R_BRACE;
540
+ mathit_text: (LETTER_NO_E | E_NOTATION_E | EXP_E)+;
541
+
542
+ frac:
543
+ CMD_FRAC L_BRACE
544
+ upper=expr
545
+ R_BRACE L_BRACE
546
+ lower=expr
547
+ R_BRACE;
548
+
549
+ //a binomial expression
550
+ binom:
551
+ L_BRACE upper=expr CMD_CHOOSE lower=expr R_BRACE
552
+ | CMD_BINOM L_BRACE upper=expr R_BRACE L_BRACE lower=expr R_BRACE;
553
+
554
+ func_normal_functions_single_arg:
555
+ FUNC_LOG | FUNC_LN | FUNC_EXP
556
+ | FUNC_SIN | FUNC_COS | FUNC_TAN
557
+ | FUNC_CSC | FUNC_SEC | FUNC_COT
558
+ | FUNC_ARCSIN | FUNC_ARCCOS | FUNC_ARCTAN
559
+ | FUNC_ARCCSC | FUNC_ARCSEC | FUNC_ARCCOT
560
+ | FUNC_SINH | FUNC_COSH | FUNC_TANH
561
+ | FUNC_ARSINH | FUNC_ARCOSH | FUNC_ARTANH
562
+ | FUNC_ARCSINH | FUNC_ARCCOSH | FUNC_ARCTANH
563
+ | FUNC_FLOOR | FUNC_CEIL | FUNC_DET;
564
+
565
+ func_normal_functions_multi_arg:
566
+ FUNC_GCD | FUNC_LCM | FUNC_MAX | FUNC_MIN;
567
+
568
+ func_operator_names_single_arg:
569
+ FUNC_ARSINH_NAME | FUNC_ARCOSH_NAME | FUNC_ARTANH_NAME
570
+ | FUNC_ARCSINH_NAME | FUNC_ARCCOSH_NAME | FUNC_ARCTANH_NAME
571
+ | FUNC_FLOOR_NAME | FUNC_CEIL_NAME | FUNC_EYE_NAME | FUNC_RANK_NAME | FUNC_TRACE_NAME
572
+ | FUNC_RREF_NAME | FUNC_NULLSPACE_NAME | FUNC_DIAGONALIZE_NAME | FUNC_NORM_NAME
573
+ | FUNC_EIGENVALS_NAME | FUNC_EIGENVECTORS_NAME | FUNC_SVD_NAME | FUNC_COLS_NAME | FUNC_ROWS_NAME;
574
+
575
+ func_operator_names_multi_arg:
576
+ FUNC_GCD_NAME | FUNC_LCM_NAME | FUNC_ZEROS_NAME | FUNC_ORTHOGONALIZE_NAME
577
+ | FUNC_ONES_NAME | FUNC_DIAG_NAME | FUNC_HSTACK_NAME | FUNC_VSTACK_NAME;
578
+
579
+ func_normal_single_arg:
580
+ (func_normal_functions_single_arg)
581
+ |
582
+ (CMD_OPERATORNAME L_BRACE func_operator_name=func_operator_names_single_arg R_BRACE);
583
+
584
+ func_normal_multi_arg:
585
+ (func_normal_functions_multi_arg)
586
+ |
587
+ (CMD_OPERATORNAME L_BRACE func_operator_name=func_operator_names_multi_arg R_BRACE);
588
+
589
+ func:
590
+ func_normal_single_arg
591
+ (subexpr? supexpr? | supexpr? subexpr?)
592
+ (L_LEFT? L_PAREN func_single_arg R_RIGHT? R_PAREN | ML_LEFT? L_PAREN func_single_arg MR_RIGHT? R_PAREN | func_single_arg_noparens)
593
+
594
+ | func_normal_multi_arg
595
+ (subexpr? supexpr? | supexpr? subexpr?)
596
+ (L_LEFT? L_PAREN func_multi_arg R_RIGHT? R_PAREN | ML_LEFT? L_PAREN func_multi_arg MR_RIGHT? R_PAREN | func_multi_arg_noparens)
597
+
598
+ | atom_expr_no_supexpr supexpr?
599
+ L_LEFT? (L_PAREN | L_BRACKET) func_common_args (R_PAREN | R_BRACKET) R_RIGHT?
600
+ | atom_expr_no_supexpr supexpr?
601
+ L_BRACE L_LEFT? (L_PAREN | L_BRACKET) func_common_args (R_PAREN | R_BRACKET) R_RIGHT? R_BRACE
602
+
603
+ | FUNC_INT
604
+ (subexpr supexpr | supexpr subexpr | (UNDERSCORE L_BRACE R_BRACE) (CARET L_BRACE R_BRACE) | (CARET L_BRACE R_BRACE) (UNDERSCORE L_BRACE R_BRACE) )?
605
+ (additive? DIFFERENTIAL | frac | additive)
606
+
607
+ | FUNC_SQRT
608
+ (L_BRACKET root=expr R_BRACKET)?
609
+ L_BRACE base=expr R_BRACE
610
+
611
+ | (FUNC_SUM | FUNC_PROD)
612
+ (subeq supexpr | supexpr subeq)
613
+ mp
614
+ | FUNC_LIM limit_sub mp
615
+ | EXP_E supexpr?; //Exponential function e^x
616
+
617
+ args: (expr ',' args) | expr;
618
+
619
+ func_common_args: atom | (expr ',') | (expr ',' args);
620
+
621
+ limit_sub:
622
+ UNDERSCORE L_BRACE
623
+ (LETTER_NO_E | GREEK_CMD | OTHER_SYMBOL_CMD)
624
+ LIM_APPROACH_SYM
625
+ expr (CARET L_BRACE (ADD | SUB) R_BRACE)?
626
+ R_BRACE;
627
+
628
+ func_single_arg: expr;
629
+ func_single_arg_noparens: mp_nofunc;
630
+
631
+ func_multi_arg: expr | (expr ',' func_multi_arg);
632
+ func_multi_arg_noparens: mp_nofunc;
633
+
634
+ subexpr: UNDERSCORE (atom | L_BRACE (expr | args) R_BRACE);
635
+ supexpr: CARET (atom | L_BRACE expr R_BRACE);
636
+
637
+ subeq: UNDERSCORE L_BRACE equality R_BRACE;
638
+ supeq: UNDERSCORE L_BRACE equality R_BRACE;
latex2sympy/README.md ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ![Logo](https://picgo-1258602555.cos.ap-nanjing.myqcloud.com/icon.png)
2
+
3
+ # [latex2sympy2](https://github.com/OrangeX4/latex2sympy)
4
+
5
+ ## About
6
+
7
+ `latex2sympy2` parses **LaTeX math expressions** and converts it into the equivalent **SymPy form**. The latex2sympy2 is adapted from [augustt198/latex2sympy](https://github.com/augustt198/latex2sympy) and [purdue-tlt / latex2sympy](https://github.com/purdue-tlt/latex2sympy).
8
+
9
+ This project is a part of a VS Code extension called [Latex Sympy Calculator](https://marketplace.visualstudio.com/items?itemName=OrangeX4.latex-sympy-calculator). It is designed for providing people writing in latex or markdown a ability to calculate something when writing math expression.
10
+
11
+ [ANTLR](http://www.antlr.org/) is used to generate the parser.
12
+
13
+ ## Features
14
+
15
+ * **Arithmetic:** Add (+), Sub (-), Dot Mul (·), Cross Mul (×), Frac (/), Power (^), Abs (|x|), Sqrt (√), etc...
16
+ * **Alphabet:** a - z, A - Z, α - ω, Subscript (x_1), Accent Bar(ā), etc...
17
+ * **Common Functions:** gcd, lcm, floor, ceil, max, min, log, ln, exp, sin, cos, tan, csc, sec, cot, arcsin, sinh, arsinh, etc...
18
+ * **Funcion Symbol:** f(x), f(x-1,), g(x,y), etc...
19
+ * **Calculous:** Limit ($lim_{n\to\infty}$), Derivation ($\frac{d}{dx}(x^2+x)$), Integration ($\int xdx$), etc...
20
+ * **Linear Algebra:** Matrix, Determinant, Transpose, Inverse, Elementary Transformation, etc...
21
+ * **Other:** Binomial...
22
+
23
+ **NOTICE:** It will do some irreversible calculations when converting determinants, transposed matrixes and elementary transformations...
24
+
25
+ ## Installation
26
+
27
+ ```
28
+ pip install latex2sympy2
29
+ ```
30
+
31
+ **Requirements:** `sympy` and `antlr4-python3-runtime` packages.
32
+
33
+ ## Usage
34
+
35
+ ### Basic
36
+
37
+ In Python:
38
+
39
+ ```python
40
+ from latex2sympy2 import latex2sympy, latex2latex
41
+
42
+ tex = r"\frac{d}{dx}(x^{2}+x)"
43
+ # Or you can use '\mathrm{d}' to replace 'd'
44
+ latex2sympy(tex)
45
+ # => "Derivative(x**2 + x, x)"
46
+ latex2latex(tex)
47
+ # => "2 x + 1"
48
+ ```
49
+
50
+ ### Examples
51
+
52
+ |LaTeX|Converted SymPy|Calculated Latex|
53
+ |-----|-----|---------------|
54
+ |`x^{3}` $x^{3}$| `x**3`|`x^{3}` $x^{3}$|
55
+ |`\frac{d}{dx} tx` $\frac{d}{dx}tx$|`Derivative(x*t, x)`|`t` $t$|
56
+ |`\sum_{i = 1}^{n} i` $\sum_{i = 1}^{n} i$|`Sum(i, (i, 1, n))`|`\frac{n \left(n + 1\right)}{2}` $\frac{n \left(n + 1\right)}{2}$|
57
+ |`\int_{a}^{b} \frac{dt}{t}`|`Integral(1/t, (t, a, b))`|`-\log{(a)} + \log{(b)}` $-\log{(a)} + \log{(b)}$|
58
+ |`(2x^3 - x + z)|_{x=3}` $(2x^3 - x + z)\|_{x=3}$|`z + 51`| `z + 51` $z + 51$ |
59
+
60
+ If you want to read the math formula, you can click [GitNotes](https://notes.orangex4.cool/?git=github&github=OrangeX4/latex2sympy).
61
+
62
+ ### Solve Equation
63
+
64
+ ``` latex
65
+ # Before
66
+ x + y = 1
67
+
68
+ # After
69
+ [ y = 1 - x, \ x = 1 - y]
70
+ ```
71
+
72
+ ### Eval At
73
+
74
+ ``` latex
75
+ # Before
76
+ (x+2)|_{x=y+1}
77
+
78
+ # After
79
+ y + 3
80
+ ```
81
+
82
+ ### Matrix
83
+
84
+ #### Identity matrix
85
+
86
+ ```
87
+ tex = r"\bm{I}_3"
88
+ latex2sympy(tex)
89
+ # => "Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])"
90
+ ```
91
+
92
+ #### Determinant
93
+
94
+ ``` python
95
+ from latex2sympy2 import latex2sympy
96
+
97
+ tex = r"\begin{vmatrix} x & 0 & 0 \\ 0 & x & 0 \\ 0 & 0 & x \end{vmatrix}"
98
+ latex2sympy(tex)
99
+ # => "x^{3}"
100
+ ```
101
+
102
+ #### Transpose
103
+
104
+ ``` python
105
+ from latex2sympy2 import latex2sympy
106
+
107
+ tex = r"\begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}^T"
108
+ # Or you can use "\begin{pmatrix}1&2&3\\4&5&6\\7&8&9\end{pmatrix}'"
109
+ latex2sympy(tex)
110
+ # => "Matrix([[1, 4, 7], [2, 5, 8], [3, 6, 9]])"
111
+ ```
112
+
113
+ #### Elementary Transformation
114
+
115
+ ``` python
116
+ from latex2sympy2 import latex2sympy
117
+
118
+ matrix = r'''
119
+ \begin{pmatrix}
120
+ 1 & 2 & 3 \\
121
+ 4 & 5 & 6 \\
122
+ 7 & 8 & 9 \\
123
+ \end{pmatrix}
124
+ '''
125
+
126
+ # Scale the row with grammar "\xrightarrow{kr_n}"
127
+ tex = matrix + r'\xrightarrow{3r_1}'
128
+ latex2sympy(tex)
129
+ # => "Matrix([[3, 6, 9], [4, 5, 6], [7, 8, 9]])"
130
+
131
+ # Swap the cols with grammar "\xrightarrow{c_1<=>c_2}"
132
+ # Of course, you can use "\leftrightarrow" to replace "<=>"
133
+ tex = matrix + r'\xrightarrow{c_1<=>c_2}'
134
+ latex2sympy(tex)
135
+ # => "Matrix([[2, 1, 3], [5, 4, 6], [8, 7, 9]])"
136
+
137
+ # Scale the second row and add it to the first row
138
+ # with grammar "\xrightarrow{r_1+kr_2}"
139
+ tex = matrix + r'\xrightarrow{r_1+kr_2}'
140
+ latex2sympy(tex)
141
+ # => "Matrix([[4*k + 1, 5*k + 2, 6*k + 3], [4, 5, 6], [7, 8, 9]])"
142
+
143
+ # You can compose the transform with comma ","
144
+ # and grammar "\xrightarrow[4r_3]{2r_1, 3r_2}"
145
+ # Remember the priority of "{}" is higher than "[]"
146
+ tex = matrix + r'\xrightarrow[4r_3]{2r_1, 3r_2}'
147
+ latex2sympy(tex)
148
+ # => "Matrix([[2, 4, 6], [12, 15, 18], [28, 32, 36]])"
149
+ ```
150
+
151
+ ### Variances
152
+
153
+ ``` python
154
+ from latex2sympy2 import latex2sympy, variances, var, set_variances
155
+
156
+ # Assign x a value of 1
157
+ latex2sympy(r"x = 1")
158
+
159
+ # Assign x a matrix symbol with dimension of n x m
160
+ latex2sympy(r"x \in \mathbb{R}^{n \times m}")
161
+
162
+ # Calculate x + y
163
+ latex2sympy(r"x + y")
164
+ # => "y + 1"
165
+
166
+ # Get all variances
167
+ print(variances)
168
+ # => "{x: 1}"
169
+
170
+ # Get variance of "x"
171
+ print(var["x"])
172
+ # => "1"
173
+
174
+ # Reset all variances
175
+ set_variances({})
176
+ latex2sympy(r"x + y")
177
+ # => "x + y"
178
+ ```
179
+
180
+ ### Complex Number Support
181
+
182
+ ``` python
183
+ from latex2sympy2 import set_real
184
+
185
+ set_real(False)
186
+ ```
187
+
188
+
189
+ ## Contributing
190
+
191
+ If you want to add a new grammar, you can fork the code from [OrangeX4/latex2sympy](https://github.com/OrangeX4/latex2sympy).
192
+
193
+ * To modify parser grammar, view the existing structure in `PS.g4`.
194
+ * To modify the action associated with each grammar, look into `latex2sympy.py`.
195
+
196
+ Contributors are welcome! Feel free to open a pull request or an issue.
latex2sympy/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ import latex2sympy
latex2sympy/antlr-4.11.1-complete.jar ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:62975e192b4af2622b72b5f0131553ee3cbce97f76dc2a41632dcc55e25473e1
3
+ size 3547867
latex2sympy/asciimath_printer.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sympy.printing.str import StrPrinter
2
+ from sympy.core import S
3
+
4
+ class AsciiMathPrinter(StrPrinter):
5
+
6
+ def _print_Limit(self, expr):
7
+ e, z = expr.args
8
+
9
+ return "lim_(%s -> %s) %s" % (self._print(z), self._print(z), self._print(e))
10
+
11
+ def _print_Integral(self, expr):
12
+ e, lims = expr.args
13
+ if len(lims) > 1:
14
+ return "int_(%s)^(%s) %s d%s" % (self._print(lims[1]), self._print(lims[2]), self._print(e), self._print(lims[0]))
15
+ else:
16
+ return "int %s d%s" % (self._print(e), self._print(lims))
17
+
18
+ def _print_Sum(self, expr):
19
+ e, lims = expr.args
20
+ return "sum_(%s = %s)^(%s) %s" % (self._print(lims[0]), self._print(lims[1]), self._print(lims[2]), self._print(e))
21
+
22
+ def _print_Product(self, expr):
23
+ e, lims = expr.args
24
+ return "prod_(%s = %s)^(%s) %s" % (self._print(lims[0]), self._print(lims[1]), self._print(lims[2]), self._print(e))
25
+
26
+ def _print_factorial(self, expr):
27
+ return "%s!" % self._print(expr.args[0])
28
+
29
+ def _print_Derivative(self, expr):
30
+ e = expr.args[0]
31
+ wrt = expr.args[1]
32
+ return "d/d%s %s" % (self._print(wrt), self._print(e))
33
+
34
+ def _print_Abs(self, expr):
35
+ return "|%s|" % self._print(expr.args[0])
36
+
37
+ def _print_Equality(self, expr):
38
+ return "%s = %s" % (self._print(expr.args[0]), self._print(expr.args[1]))
39
+
40
+ def _print_Pow(self, expr):
41
+ b = self._print(expr.base)
42
+ if expr.exp is S.Half:
43
+ return "sqrt(%s)" % b
44
+
45
+ if -expr.exp is S.Half:
46
+ return "1/sqrt(%s)" % b
47
+ if expr.exp is -S.One:
48
+ return "1/%s" % b
49
+
50
+ return "%s^(%s)" % (b, self._print(expr.exp))
latex2sympy/description.txt ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ latex2sympy2: https://github.com/OrangeX4/latex2sympy
2
+
3
+ About
4
+
5
+ `latex2sympy2` parses **LaTeX math expressions** and converts it into the equivalent **SymPy form**. The latex2sympy2 is adapted from [augustt198/latex2sympy](https://github.com/augustt198/latex2sympy) and [purdue-tlt / latex2sympy](https://github.com/purdue-tlt/latex2sympy).
6
+
7
+ [ANTLR](http://www.antlr.org/) is used to generate the parser.
8
+
9
+ Features
10
+
11
+ * **Arithmetic:** Add (+), Sub (-), Dot Mul (·), Cross Mul (×), Frac (/), Power (^), Abs (|x|), Sqrt (√), etc...
12
+ * **Alphabet:** a - z, A - Z, α - ω, Subscript (x_1), Accent Bar(ā), etc...
13
+ * **Common Functions:** gcd, lcm, floor, ceil, max, min, log, ln, exp, sin, cos, tan, csc, sec, cot, arcsin, sinh, arsinh, etc...
14
+ * **Calculous:** Limit ($lim_{n\to\infty}$), Derivation ($\frac{d}{dx}(x^2+x)$), Integration ($\int xdx$), etc...
15
+ * **Linear Algebra:** Matrix, Determinant, Transpose, Inverse, Elementary Transformation, etc...
16
+ * **Other:** Binomial...
17
+
18
+ **NOTICE:** It will do some irreversible calculations when converting determinants, transposed matrixes and elementary transformations...
19
+
20
+ Installation
21
+
22
+ ```
23
+ pip install latex2sympy2
24
+ ```
25
+
26
+ **Requirements:** `sympy` and `antlr4-python3-runtime` packages.
27
+
28
+ Usage
29
+
30
+ Basic
31
+
32
+ In Python:
33
+
34
+ ```python
35
+ from latex2sympy2 import latex2sympy, latex2latex
36
+
37
+ tex = r"\frac{d}{dx}(x^{2}+x)"
38
+ # Or you can use '\mathrm{d}' to replace 'd'
39
+ latex2sympy(tex)
40
+ # => "Derivative(x**2 + x, x)"
41
+ latex2latex(tex)
42
+ # => "2 x + 1"
43
+ ```
44
+
45
+ Examples
46
+
47
+ |LaTeX|Converted SymPy|Calculated Latex|
48
+ |-----|-----|---------------|
49
+ |`x^{3}` $x^{3}$| `x**3`|`x^{3}` $x^{3}$|
50
+ |`\frac{d}{dx} tx` $\frac{d}{dx}tx$|`Derivative(x*t, x)`|`t` $t$|
51
+ |`\sum_{i = 1}^{n} i` $\sum_{i = 1}^{n} i$|`Sum(i, (i, 1, n))`|`\frac{n \left(n + 1\right)}{2}` $\frac{n \left(n + 1\right)}{2}$|
52
+ |`\int_{a}^{b} \frac{dt}{t}`|`Integral(1/t, (t, a, b))`|`-\log{(a)} + \log{(b)}` $-\log{(a)} + \log{(b)}$|
53
+ |`(2x^3 - x + z)|_{x=3}` $(2x^3 - x + z)\|_{x=3}$|`z + 51`| `z + 51` $z + 51$ |
54
+
55
+ If you want to read the math formula, you can click [GitNotes](https://notes.orangex4.cool/?git=github&github=OrangeX4/latex2sympy).
56
+
57
+ Matrix
58
+
59
+ Determinant
60
+
61
+ ``` python
62
+ from latex2sympy2 import latex2sympy
63
+
64
+ tex = r"\begin{vmatrix} x & 0 & 0 \\ 0 & x & 0 \\ 0 & 0 & x \end{vmatrix}"
65
+ latex2sympy(tex)
66
+ # => "x^{3}"
67
+ ```
68
+
69
+ Transpose
70
+
71
+ ``` python
72
+ from latex2sympy2 import latex2sympy
73
+
74
+ tex = r"\begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}^T"
75
+ # Or you can use "\begin{pmatrix}1&2&3\\4&5&6\\7&8&9\end{pmatrix}'"
76
+ latex2sympy(tex)
77
+ # => "Matrix([[1, 4, 7], [2, 5, 8], [3, 6, 9]])"
78
+ ```
79
+
80
+ Elementary Transformation
81
+
82
+ ``` python
83
+ from latex2sympy2 import latex2sympy
84
+
85
+ matrix = r'''
86
+ \begin{pmatrix}
87
+ 1 & 2 & 3 \\
88
+ 4 & 5 & 6 \\
89
+ 7 & 8 & 9 \\
90
+ \end{pmatrix}
91
+ '''
92
+
93
+ # Scale the row with grammar "\xrightarrow{kr_n}"
94
+ tex = matrix + r'\xrightarrow{3r_1}'
95
+ latex2sympy(tex)
96
+ # => "Matrix([[3, 6, 9], [4, 5, 6], [7, 8, 9]])"
97
+
98
+ # Swap the cols with grammar "\xrightarrow{c_1<=>c_2}"
99
+ # Of course, you can use "\leftrightarrow" to replace "<=>"
100
+ tex = matrix + r'\xrightarrow{c_1<=>c_2}'
101
+ latex2sympy(tex)
102
+ # => "Matrix([[2, 1, 3], [5, 4, 6], [8, 7, 9]])"
103
+
104
+ # Scale the second row and add it to the first row
105
+ # with grammar "\xrightarrow{r_1+kr_2}"
106
+ tex = matrix + r'\xrightarrow{r_1+kr_2}'
107
+ latex2sympy(tex)
108
+ # => "Matrix([[4*k + 1, 5*k + 2, 6*k + 3], [4, 5, 6], [7, 8, 9]])"
109
+
110
+ # You can compose the transform with comma ","
111
+ # and grammar "\xrightarrow[4r_3]{2r_1, 3r_2}"
112
+ # Remember the priority of "{}" is higher than "[]"
113
+ tex = matrix + r'\xrightarrow[4r_3]{2r_1, 3r_2}'
114
+ latex2sympy(tex)
115
+ # => "Matrix([[2, 4, 6], [12, 15, 18], [28, 32, 36]])"
116
+ ```
117
+
118
+ Variances
119
+
120
+ ``` python
121
+ from latex2sympy2 import latex2sympy, variances, var, set_variances
122
+
123
+ # Assign x a value of 1
124
+ latex2sympy(r"x = 1")
125
+
126
+ # Calculate x + y
127
+ latex2sympy(r"x + y")
128
+ # => "y + 1"
129
+
130
+ # Get all variances
131
+ print(variances)
132
+ # => "{x: 1}"
133
+
134
+ # Get variance of "x"
135
+ print(var["x"])
136
+ # => "1"
137
+
138
+ # Reset all variances
139
+ set_variances({})
140
+ latex2sympy(r"x + y")
141
+ # => "x + y"
142
+ ```
143
+
144
+
145
+ Contributing
146
+
147
+ If you want to add a new grammar, you can fork the code from [OrangeX4/latex2sympy](https://github.com/OrangeX4/latex2sympy).
148
+
149
+ * To modify parser grammar, view the existing structure in `PS.g4`.
150
+ * To modify the action associated with each grammar, look into `latex2sympy.py`.
151
+
152
+ Contributors are welcome! Feel free to open a pull request or an issue.
latex2sympy/dev-requirements.in ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ -r requirements.txt
2
+ # Development
3
+ pip-tools
4
+ pytest
5
+ pytest-cov
6
+ pycodestyle
7
+ autopep8
8
+ -e .
latex2sympy/dev-requirements.txt ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.10
3
+ # by the following command:
4
+ #
5
+ # pip-compile dev-requirements.in
6
+ #
7
+ # via -r dev-requirements.in
8
+ antlr4-python3-runtime==4.11.1
9
+ # via
10
+ # -r requirements.txt
11
+ # latex2sympy2
12
+ atomicwrites==1.3.0
13
+ # via pytest
14
+ attrs==19.3.0
15
+ # via pytest
16
+ autopep8==1.4.4
17
+ # via -r dev-requirements.in
18
+ click==7.0
19
+ # via pip-tools
20
+ coverage==4.5.4
21
+ # via pytest-cov
22
+ more-itertools==7.2.0
23
+ # via pytest
24
+ mpmath==1.3.0
25
+ # via
26
+ # -r requirements.txt
27
+ # sympy
28
+ packaging==19.2
29
+ # via pytest
30
+ pip-tools==4.2.0
31
+ # via -r dev-requirements.in
32
+ pluggy==0.13.0
33
+ # via pytest
34
+ py==1.8.0
35
+ # via pytest
36
+ pycodestyle==2.5.0
37
+ # via
38
+ # -r dev-requirements.in
39
+ # autopep8
40
+ pyparsing==2.4.4
41
+ # via packaging
42
+ pytest==5.2.2
43
+ # via
44
+ # -r dev-requirements.in
45
+ # pytest-cov
46
+ pytest-cov==2.8.1
47
+ # via -r dev-requirements.in
48
+ six==1.13.0
49
+ # via
50
+ # packaging
51
+ # pip-tools
52
+ sympy==1.12
53
+ # via
54
+ # -r requirements.txt
55
+ # latex2sympy2
56
+ wcwidth==0.1.7
57
+ # via pytest
58
+
59
+ # THIS MUST BE MAINTAINED AS-IS
60
+ -e .
latex2sympy/gen/PS.interp ADDED
@@ -0,0 +1,462 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ token literal names:
2
+ null
3
+ '\\acute'
4
+ '\\bar'
5
+ '\\overline'
6
+ '\\breve'
7
+ '\\check'
8
+ '\\widecheck'
9
+ '\\dot'
10
+ '\\ddot'
11
+ '\\grave'
12
+ '\\hat'
13
+ '\\tilde'
14
+ '\\widetilde'
15
+ '\\vec'
16
+ '\\overrightarrow'
17
+ '\\bm'
18
+ '\\boldsymbol'
19
+ '\\text'
20
+ '\\textit'
21
+ '\\mathbb'
22
+ '\\mathbin'
23
+ '\\mathbf'
24
+ '\\mathcal'
25
+ '\\mathclap'
26
+ '\\mathclose'
27
+ '\\mathellipsis'
28
+ '\\mathfrak'
29
+ '\\mathinner'
30
+ '\\mathnormal'
31
+ '\\mathop'
32
+ '\\mathopen'
33
+ '\\mathord'
34
+ '\\mathpunct'
35
+ '\\mathrel'
36
+ '\\mathring'
37
+ '\\mathrlap'
38
+ '\\mathrm'
39
+ '\\mathscr'
40
+ '\\mathsf'
41
+ '\\mathsterling'
42
+ '\\mathtt'
43
+ '^T'
44
+ '^{T}'
45
+ '^{\\top}'
46
+ '\''
47
+ null
48
+ '\\$'
49
+ '+'
50
+ '-'
51
+ '*'
52
+ null
53
+ '('
54
+ ')'
55
+ '\\lgroup'
56
+ '\\rgroup'
57
+ '{'
58
+ '}'
59
+ '\\{'
60
+ '\\}'
61
+ '\\lbrace'
62
+ '\\rbrace'
63
+ '['
64
+ ']'
65
+ '\\lbrack'
66
+ '\\rbrack'
67
+ '|'
68
+ '\\lvert'
69
+ '\\rvert'
70
+ '\\vert'
71
+ '\\|'
72
+ '\\lfloor'
73
+ '\\rfloor'
74
+ '\\llcorner'
75
+ '\\lrcorner'
76
+ '\\lceil'
77
+ '\\rceil'
78
+ '\\ulcorner'
79
+ '\\urcorner'
80
+ '\\left'
81
+ '\\right'
82
+ '\\mleft'
83
+ '\\mright'
84
+ '\\lim'
85
+ null
86
+ '\\int'
87
+ '\\sum'
88
+ '\\prod'
89
+ '\\log'
90
+ '\\ln'
91
+ '\\exp'
92
+ '\\sin'
93
+ '\\cos'
94
+ '\\tan'
95
+ '\\csc'
96
+ '\\sec'
97
+ '\\cot'
98
+ '\\arcsin'
99
+ '\\arccos'
100
+ '\\arctan'
101
+ '\\arccsc'
102
+ '\\arcsec'
103
+ '\\arccot'
104
+ '\\sinh'
105
+ '\\cosh'
106
+ '\\tanh'
107
+ '\\arsinh'
108
+ '\\arcosh'
109
+ '\\artanh'
110
+ '\\arcsinh'
111
+ '\\arccosh'
112
+ '\\arctanh'
113
+ 'arsinh'
114
+ 'arcsinh'
115
+ 'arcosh'
116
+ 'arccosh'
117
+ 'artanh'
118
+ 'arctanh'
119
+ 'gcd'
120
+ 'lcm'
121
+ 'floor'
122
+ 'ceil'
123
+ '\\sqrt'
124
+ '\\gcd'
125
+ '\\lcm'
126
+ '\\floor'
127
+ '\\ceil'
128
+ '\\max'
129
+ '\\min'
130
+ '\\det'
131
+ 'eye'
132
+ 'zeros'
133
+ 'ones'
134
+ 'cols'
135
+ 'rows'
136
+ 'diag'
137
+ 'norm'
138
+ 'rank'
139
+ null
140
+ 'rref'
141
+ 'hstack'
142
+ 'vstack'
143
+ null
144
+ 'nullspace'
145
+ null
146
+ null
147
+ null
148
+ null
149
+ '\\times'
150
+ '\\cdot'
151
+ '\\div'
152
+ '\\frac'
153
+ null
154
+ '\\choose'
155
+ '\\mod'
156
+ '\\mathit'
157
+ '\\operatorname'
158
+ 'matrix'
159
+ 'pmatrix'
160
+ 'bmatrix'
161
+ 'vmatrix'
162
+ null
163
+ null
164
+ null
165
+ null
166
+ null
167
+ '&'
168
+ '\\\\'
169
+ '_'
170
+ '^'
171
+ ':'
172
+ ';'
173
+ ','
174
+ '.'
175
+ null
176
+ null
177
+ 'E'
178
+ null
179
+ null
180
+ null
181
+ null
182
+ null
183
+ '\\in'
184
+ '='
185
+ null
186
+ '<'
187
+ null
188
+ '>'
189
+ null
190
+ null
191
+ '!'
192
+ null
193
+ null
194
+ null
195
+ null
196
+ null
197
+
198
+ token symbolic names:
199
+ null
200
+ null
201
+ null
202
+ null
203
+ null
204
+ null
205
+ null
206
+ null
207
+ null
208
+ null
209
+ null
210
+ null
211
+ null
212
+ null
213
+ null
214
+ null
215
+ null
216
+ null
217
+ null
218
+ null
219
+ null
220
+ null
221
+ null
222
+ null
223
+ null
224
+ null
225
+ null
226
+ null
227
+ null
228
+ null
229
+ null
230
+ null
231
+ null
232
+ null
233
+ null
234
+ null
235
+ null
236
+ null
237
+ null
238
+ null
239
+ null
240
+ null
241
+ null
242
+ null
243
+ null
244
+ WS
245
+ DOLLAR_SIGN
246
+ ADD
247
+ SUB
248
+ MUL
249
+ DIV
250
+ L_PAREN
251
+ R_PAREN
252
+ L_GROUP
253
+ R_GROUP
254
+ L_BRACE
255
+ R_BRACE
256
+ L_BRACE_VISUAL
257
+ R_BRACE_VISUAL
258
+ L_BRACE_CMD
259
+ R_BRACE_CMD
260
+ L_BRACKET
261
+ R_BRACKET
262
+ L_BRACK
263
+ R_BRACK
264
+ BAR
265
+ L_VERT
266
+ R_VERT
267
+ VERT
268
+ NORM
269
+ L_FLOOR
270
+ R_FLOOR
271
+ LL_CORNER
272
+ LR_CORNER
273
+ L_CEIL
274
+ R_CEIL
275
+ UL_CORNER
276
+ UR_CORNER
277
+ L_LEFT
278
+ R_RIGHT
279
+ ML_LEFT
280
+ MR_RIGHT
281
+ FUNC_LIM
282
+ LIM_APPROACH_SYM
283
+ FUNC_INT
284
+ FUNC_SUM
285
+ FUNC_PROD
286
+ FUNC_LOG
287
+ FUNC_LN
288
+ FUNC_EXP
289
+ FUNC_SIN
290
+ FUNC_COS
291
+ FUNC_TAN
292
+ FUNC_CSC
293
+ FUNC_SEC
294
+ FUNC_COT
295
+ FUNC_ARCSIN
296
+ FUNC_ARCCOS
297
+ FUNC_ARCTAN
298
+ FUNC_ARCCSC
299
+ FUNC_ARCSEC
300
+ FUNC_ARCCOT
301
+ FUNC_SINH
302
+ FUNC_COSH
303
+ FUNC_TANH
304
+ FUNC_ARSINH
305
+ FUNC_ARCOSH
306
+ FUNC_ARTANH
307
+ FUNC_ARCSINH
308
+ FUNC_ARCCOSH
309
+ FUNC_ARCTANH
310
+ FUNC_ARSINH_NAME
311
+ FUNC_ARCSINH_NAME
312
+ FUNC_ARCOSH_NAME
313
+ FUNC_ARCCOSH_NAME
314
+ FUNC_ARTANH_NAME
315
+ FUNC_ARCTANH_NAME
316
+ FUNC_GCD_NAME
317
+ FUNC_LCM_NAME
318
+ FUNC_FLOOR_NAME
319
+ FUNC_CEIL_NAME
320
+ FUNC_SQRT
321
+ FUNC_GCD
322
+ FUNC_LCM
323
+ FUNC_FLOOR
324
+ FUNC_CEIL
325
+ FUNC_MAX
326
+ FUNC_MIN
327
+ FUNC_DET
328
+ FUNC_EYE_NAME
329
+ FUNC_ZEROS_NAME
330
+ FUNC_ONES_NAME
331
+ FUNC_COLS_NAME
332
+ FUNC_ROWS_NAME
333
+ FUNC_DIAG_NAME
334
+ FUNC_NORM_NAME
335
+ FUNC_RANK_NAME
336
+ FUNC_TRACE_NAME
337
+ FUNC_RREF_NAME
338
+ FUNC_HSTACK_NAME
339
+ FUNC_VSTACK_NAME
340
+ FUNC_ORTHOGONALIZE_NAME
341
+ FUNC_NULLSPACE_NAME
342
+ FUNC_DIAGONALIZE_NAME
343
+ FUNC_EIGENVALS_NAME
344
+ FUNC_EIGENVECTORS_NAME
345
+ FUNC_SVD_NAME
346
+ CMD_TIMES
347
+ CMD_CDOT
348
+ CMD_DIV
349
+ CMD_FRAC
350
+ CMD_BINOM
351
+ CMD_CHOOSE
352
+ CMD_MOD
353
+ CMD_MATHIT
354
+ CMD_OPERATORNAME
355
+ MATRIX_TYPE_MATRIX
356
+ MATRIX_TYPE_PMATRIX
357
+ MATRIX_TYPE_BMATRIX
358
+ MATRIX_TYPE_DET
359
+ MATRIX_TYPES
360
+ CMD_MATRIX_START
361
+ CMD_MATRIX_END
362
+ CMD_DET_START
363
+ CMD_DET_END
364
+ MATRIX_DEL_COL
365
+ MATRIX_DEL_ROW
366
+ UNDERSCORE
367
+ CARET
368
+ COLON
369
+ SEMICOLON
370
+ COMMA
371
+ PERIOD
372
+ DIFFERENTIAL
373
+ EXP_E
374
+ E_NOTATION_E
375
+ LETTER_NO_E
376
+ MATRIX_XRIGHTARROW
377
+ TRANSFORM_EXCHANGE
378
+ NUMBER
379
+ E_NOTATION
380
+ IN
381
+ ASSIGNMENT
382
+ EQUAL
383
+ LT
384
+ LTE
385
+ GT
386
+ GTE
387
+ UNEQUAL
388
+ BANG
389
+ PERCENT_NUMBER
390
+ GREEK_CMD
391
+ OTHER_SYMBOL_CMD
392
+ SYMBOL
393
+ VARIABLE
394
+
395
+ rule names:
396
+ accent_symbol
397
+ math
398
+ transpose
399
+ transform_atom
400
+ transform_scale
401
+ transform_swap
402
+ transform_assignment
403
+ elementary_transform
404
+ elementary_transforms
405
+ matrix
406
+ det
407
+ matrix_row
408
+ relation
409
+ relation_list
410
+ relation_list_content
411
+ equality
412
+ expr
413
+ additive
414
+ mp
415
+ mp_nofunc
416
+ unary
417
+ unary_nofunc
418
+ postfix
419
+ postfix_nofunc
420
+ postfix_op
421
+ eval_at
422
+ eval_at_sub
423
+ eval_at_sup
424
+ exp
425
+ exp_nofunc
426
+ comp
427
+ comp_nofunc
428
+ group
429
+ norm_group
430
+ abs_group
431
+ floor_group
432
+ ceil_group
433
+ accent
434
+ atom_expr_no_supexpr
435
+ atom_expr
436
+ atom
437
+ mathit
438
+ mathit_text
439
+ frac
440
+ binom
441
+ func_normal_functions_single_arg
442
+ func_normal_functions_multi_arg
443
+ func_operator_names_single_arg
444
+ func_operator_names_multi_arg
445
+ func_normal_single_arg
446
+ func_normal_multi_arg
447
+ func
448
+ args
449
+ func_common_args
450
+ limit_sub
451
+ func_single_arg
452
+ func_single_arg_noparens
453
+ func_multi_arg
454
+ func_multi_arg_noparens
455
+ subexpr
456
+ supexpr
457
+ subeq
458
+ supeq
459
+
460
+
461
+ atn:
462
+ [4, 1, 194, 1046, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 1, 0, 1, 0, 1, 1, 1, 1, 3, 1, 131, 8, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 141, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 147, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 3, 7, 161, 8, 7, 1, 8, 1, 8, 1, 8, 5, 8, 166, 8, 8, 10, 8, 12, 8, 169, 9, 8, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 175, 8, 9, 10, 9, 12, 9, 178, 9, 9, 1, 9, 3, 9, 181, 8, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 189, 8, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 195, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 201, 8, 10, 10, 10, 12, 10, 204, 9, 10, 1, 10, 3, 10, 207, 8, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 5, 11, 214, 8, 11, 10, 11, 12, 11, 217, 9, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 5, 12, 225, 8, 12, 10, 12, 12, 12, 228, 9, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 267, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 274, 8, 14, 10, 14, 12, 14, 277, 9, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 284, 8, 14, 10, 14, 12, 14, 287, 9, 14, 3, 14, 289, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 5, 17, 303, 8, 17, 10, 17, 12, 17, 306, 9, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 5, 18, 314, 8, 18, 10, 18, 12, 18, 317, 9, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 5, 19, 325, 8, 19, 10, 19, 12, 19, 328, 9, 19, 1, 20, 1, 20, 1, 20, 4, 20, 333, 8, 20, 11, 20, 12, 20, 334, 3, 20, 337, 8, 20, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 343, 8, 21, 10, 21, 12, 21, 346, 9, 21, 3, 21, 348, 8, 21, 1, 22, 1, 22, 5, 22, 352, 8, 22, 10, 22, 12, 22, 355, 9, 22, 1, 23, 1, 23, 5, 23, 359, 8, 23, 10, 23, 12, 23, 362, 9, 23, 1, 24, 1, 24, 1, 24, 3, 24, 367, 8, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 3, 25, 375, 8, 25, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 381, 8, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 3, 27, 389, 8, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 3, 28, 403, 8, 28, 1, 28, 3, 28, 406, 8, 28, 5, 28, 408, 8, 28, 10, 28, 12, 28, 411, 9, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 423, 8, 29, 1, 29, 3, 29, 426, 8, 29, 5, 29, 428, 8, 29, 10, 29, 12, 29, 431, 9, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 3, 30, 444, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 456, 8, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 3, 32, 570, 8, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 588, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 638, 8, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, 672, 8, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 706, 8, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 717, 8, 38, 1, 38, 3, 38, 720, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 726, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 736, 8, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 3, 40, 746, 8, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 4, 42, 754, 8, 42, 11, 42, 12, 42, 755, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 780, 8, 44, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 3, 49, 796, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 3, 50, 804, 8, 50, 1, 51, 1, 51, 3, 51, 808, 8, 51, 1, 51, 3, 51, 811, 8, 51, 1, 51, 3, 51, 814, 8, 51, 1, 51, 3, 51, 817, 8, 51, 3, 51, 819, 8, 51, 1, 51, 3, 51, 822, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 827, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 832, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 837, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 842, 8, 51, 1, 51, 1, 51, 3, 51, 846, 8, 51, 1, 51, 3, 51, 849, 8, 51, 1, 51, 3, 51, 852, 8, 51, 1, 51, 3, 51, 855, 8, 51, 3, 51, 857, 8, 51, 1, 51, 3, 51, 860, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 865, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 870, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 875, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 880, 8, 51, 1, 51, 1, 51, 3, 51, 884, 8, 51, 1, 51, 3, 51, 887, 8, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 893, 8, 51, 1, 51, 1, 51, 3, 51, 897, 8, 51, 1, 51, 1, 51, 3, 51, 901, 8, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 907, 8, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 932, 8, 51, 1, 51, 3, 51, 935, 8, 51, 1, 51, 1, 51, 1, 51, 3, 51, 940, 8, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 947, 8, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 960, 8, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 3, 51, 970, 8, 51, 3, 51, 972, 8, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 3, 52, 979, 8, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 989, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 1000, 8, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 1013, 8, 57, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 3, 59, 1022, 8, 59, 1, 59, 1, 59, 3, 59, 1026, 8, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 3, 60, 1034, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 0, 6, 24, 34, 36, 38, 56, 58, 63, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 0, 15, 2, 0, 1, 40, 154, 154, 1, 0, 41, 44, 1, 0, 181, 188, 1, 0, 182, 183, 1, 0, 47, 48, 4, 0, 49, 50, 147, 149, 153, 153, 169, 169, 1, 0, 174, 176, 3, 0, 87, 110, 124, 125, 128, 128, 2, 0, 122, 123, 126, 127, 6, 0, 111, 116, 119, 120, 129, 129, 132, 133, 135, 138, 142, 146, 4, 0, 117, 118, 130, 131, 134, 134, 139, 141, 2, 0, 51, 51, 61, 61, 2, 0, 52, 52, 62, 62, 1, 0, 85, 86, 2, 0, 176, 176, 191, 192, 1164, 0, 126, 1, 0, 0, 0, 2, 130, 1, 0, 0, 0, 4, 132, 1, 0, 0, 0, 6, 134, 1, 0, 0, 0, 8, 146, 1, 0, 0, 0, 10, 150, 1, 0, 0, 0, 12, 154, 1, 0, 0, 0, 14, 160, 1, 0, 0, 0, 16, 162, 1, 0, 0, 0, 18, 170, 1, 0, 0, 0, 20, 196, 1, 0, 0, 0, 22, 210, 1, 0, 0, 0, 24, 218, 1, 0, 0, 0, 26, 266, 1, 0, 0, 0, 28, 288, 1, 0, 0, 0, 30, 290, 1, 0, 0, 0, 32, 294, 1, 0, 0, 0, 34, 296, 1, 0, 0, 0, 36, 307, 1, 0, 0, 0, 38, 318, 1, 0, 0, 0, 40, 336, 1, 0, 0, 0, 42, 347, 1, 0, 0, 0, 44, 349, 1, 0, 0, 0, 46, 356, 1, 0, 0, 0, 48, 366, 1, 0, 0, 0, 50, 368, 1, 0, 0, 0, 52, 376, 1, 0, 0, 0, 54, 384, 1, 0, 0, 0, 56, 392, 1, 0, 0, 0, 58, 412, 1, 0, 0, 0, 60, 443, 1, 0, 0, 0, 62, 455, 1, 0, 0, 0, 64, 569, 1, 0, 0, 0, 66, 587, 1, 0, 0, 0, 68, 637, 1, 0, 0, 0, 70, 671, 1, 0, 0, 0, 72, 705, 1, 0, 0, 0, 74, 707, 1, 0, 0, 0, 76, 716, 1, 0, 0, 0, 78, 725, 1, 0, 0, 0, 80, 745, 1, 0, 0, 0, 82, 747, 1, 0, 0, 0, 84, 753, 1, 0, 0, 0, 86, 757, 1, 0, 0, 0, 88, 779, 1, 0, 0, 0, 90, 781, 1, 0, 0, 0, 92, 783, 1, 0, 0, 0, 94, 785, 1, 0, 0, 0, 96, 787, 1, 0, 0, 0, 98, 795, 1, 0, 0, 0, 100, 803, 1, 0, 0, 0, 102, 971, 1, 0, 0, 0, 104, 978, 1, 0, 0, 0, 106, 988, 1, 0, 0, 0, 108, 990, 1, 0, 0, 0, 110, 1003, 1, 0, 0, 0, 112, 1005, 1, 0, 0, 0, 114, 1012, 1, 0, 0, 0, 116, 1014, 1, 0, 0, 0, 118, 1016, 1, 0, 0, 0, 120, 1027, 1, 0, 0, 0, 122, 1035, 1, 0, 0, 0, 124, 1040, 1, 0, 0, 0, 126, 127, 7, 0, 0, 0, 127, 1, 1, 0, 0, 0, 128, 131, 3, 24, 12, 0, 129, 131, 3, 26, 13, 0, 130, 128, 1, 0, 0, 0, 130, 129, 1, 0, 0, 0, 131, 3, 1, 0, 0, 0, 132, 133, 7, 1, 0, 0, 133, 5, 1, 0, 0, 0, 134, 135, 5, 176, 0, 0, 135, 140, 5, 167, 0, 0, 136, 141, 5, 179, 0, 0, 137, 138, 5, 55, 0, 0, 138, 139, 5, 179, 0, 0, 139, 141, 5, 56, 0, 0, 140, 136, 1, 0, 0, 0, 140, 137, 1, 0, 0, 0, 141, 7, 1, 0, 0, 0, 142, 147, 3, 32, 16, 0, 143, 147, 3, 64, 32, 0, 144, 147, 5, 47, 0, 0, 145, 147, 5, 48, 0, 0, 146, 142, 1, 0, 0, 0, 146, 143, 1, 0, 0, 0, 146, 144, 1, 0, 0, 0, 146, 145, 1, 0, 0, 0, 147, 148, 1, 0, 0, 0, 148, 149, 3, 6, 3, 0, 149, 9, 1, 0, 0, 0, 150, 151, 3, 6, 3, 0, 151, 152, 5, 178, 0, 0, 152, 153, 3, 6, 3, 0, 153, 11, 1, 0, 0, 0, 154, 155, 3, 6, 3, 0, 155, 156, 3, 8, 4, 0, 156, 13, 1, 0, 0, 0, 157, 161, 3, 12, 6, 0, 158, 161, 3, 8, 4, 0, 159, 161, 3, 10, 5, 0, 160, 157, 1, 0, 0, 0, 160, 158, 1, 0, 0, 0, 160, 159, 1, 0, 0, 0, 161, 15, 1, 0, 0, 0, 162, 167, 3, 14, 7, 0, 163, 164, 5, 171, 0, 0, 164, 166, 3, 14, 7, 0, 165, 163, 1, 0, 0, 0, 166, 169, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 167, 168, 1, 0, 0, 0, 168, 17, 1, 0, 0, 0, 169, 167, 1, 0, 0, 0, 170, 171, 5, 161, 0, 0, 171, 176, 3, 22, 11, 0, 172, 173, 5, 166, 0, 0, 173, 175, 3, 22, 11, 0, 174, 172, 1, 0, 0, 0, 175, 178, 1, 0, 0, 0, 176, 174, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 180, 1, 0, 0, 0, 178, 176, 1, 0, 0, 0, 179, 181, 5, 166, 0, 0, 180, 179, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 194, 5, 162, 0, 0, 183, 188, 5, 177, 0, 0, 184, 185, 5, 61, 0, 0, 185, 186, 3, 16, 8, 0, 186, 187, 5, 62, 0, 0, 187, 189, 1, 0, 0, 0, 188, 184, 1, 0, 0, 0, 188, 189, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, 191, 5, 55, 0, 0, 191, 192, 3, 16, 8, 0, 192, 193, 5, 56, 0, 0, 193, 195, 1, 0, 0, 0, 194, 183, 1, 0, 0, 0, 194, 195, 1, 0, 0, 0, 195, 19, 1, 0, 0, 0, 196, 197, 5, 163, 0, 0, 197, 202, 3, 22, 11, 0, 198, 199, 5, 166, 0, 0, 199, 201, 3, 22, 11, 0, 200, 198, 1, 0, 0, 0, 201, 204, 1, 0, 0, 0, 202, 200, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 203, 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 205, 207, 5, 166, 0, 0, 206, 205, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 208, 1, 0, 0, 0, 208, 209, 5, 164, 0, 0, 209, 21, 1, 0, 0, 0, 210, 215, 3, 32, 16, 0, 211, 212, 5, 165, 0, 0, 212, 214, 3, 32, 16, 0, 213, 211, 1, 0, 0, 0, 214, 217, 1, 0, 0, 0, 215, 213, 1, 0, 0, 0, 215, 216, 1, 0, 0, 0, 216, 23, 1, 0, 0, 0, 217, 215, 1, 0, 0, 0, 218, 219, 6, 12, -1, 0, 219, 220, 3, 32, 16, 0, 220, 226, 1, 0, 0, 0, 221, 222, 10, 2, 0, 0, 222, 223, 7, 2, 0, 0, 223, 225, 3, 24, 12, 3, 224, 221, 1, 0, 0, 0, 225, 228, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 25, 1, 0, 0, 0, 228, 226, 1, 0, 0, 0, 229, 267, 3, 28, 14, 0, 230, 231, 5, 61, 0, 0, 231, 232, 3, 28, 14, 0, 232, 233, 5, 62, 0, 0, 233, 267, 1, 0, 0, 0, 234, 235, 5, 55, 0, 0, 235, 236, 3, 28, 14, 0, 236, 237, 5, 56, 0, 0, 237, 267, 1, 0, 0, 0, 238, 239, 5, 57, 0, 0, 239, 240, 3, 28, 14, 0, 240, 241, 5, 58, 0, 0, 241, 267, 1, 0, 0, 0, 242, 243, 5, 78, 0, 0, 243, 244, 5, 61, 0, 0, 244, 245, 3, 28, 14, 0, 245, 246, 5, 79, 0, 0, 246, 247, 5, 62, 0, 0, 247, 267, 1, 0, 0, 0, 248, 249, 5, 78, 0, 0, 249, 250, 5, 57, 0, 0, 250, 251, 3, 28, 14, 0, 251, 252, 5, 79, 0, 0, 252, 253, 5, 58, 0, 0, 253, 267, 1, 0, 0, 0, 254, 255, 5, 80, 0, 0, 255, 256, 5, 61, 0, 0, 256, 257, 3, 28, 14, 0, 257, 258, 5, 81, 0, 0, 258, 259, 5, 62, 0, 0, 259, 267, 1, 0, 0, 0, 260, 261, 5, 80, 0, 0, 261, 262, 5, 57, 0, 0, 262, 263, 3, 28, 14, 0, 263, 264, 5, 81, 0, 0, 264, 265, 5, 58, 0, 0, 265, 267, 1, 0, 0, 0, 266, 229, 1, 0, 0, 0, 266, 230, 1, 0, 0, 0, 266, 234, 1, 0, 0, 0, 266, 238, 1, 0, 0, 0, 266, 242, 1, 0, 0, 0, 266, 248, 1, 0, 0, 0, 266, 254, 1, 0, 0, 0, 266, 260, 1, 0, 0, 0, 267, 27, 1, 0, 0, 0, 268, 269, 3, 24, 12, 0, 269, 270, 5, 171, 0, 0, 270, 275, 3, 24, 12, 0, 271, 272, 5, 171, 0, 0, 272, 274, 3, 24, 12, 0, 273, 271, 1, 0, 0, 0, 274, 277, 1, 0, 0, 0, 275, 273, 1, 0, 0, 0, 275, 276, 1, 0, 0, 0, 276, 289, 1, 0, 0, 0, 277, 275, 1, 0, 0, 0, 278, 279, 3, 24, 12, 0, 279, 280, 5, 170, 0, 0, 280, 285, 3, 24, 12, 0, 281, 282, 5, 170, 0, 0, 282, 284, 3, 24, 12, 0, 283, 281, 1, 0, 0, 0, 284, 287, 1, 0, 0, 0, 285, 283, 1, 0, 0, 0, 285, 286, 1, 0, 0, 0, 286, 289, 1, 0, 0, 0, 287, 285, 1, 0, 0, 0, 288, 268, 1, 0, 0, 0, 288, 278, 1, 0, 0, 0, 289, 29, 1, 0, 0, 0, 290, 291, 3, 32, 16, 0, 291, 292, 7, 3, 0, 0, 292, 293, 3, 32, 16, 0, 293, 31, 1, 0, 0, 0, 294, 295, 3, 34, 17, 0, 295, 33, 1, 0, 0, 0, 296, 297, 6, 17, -1, 0, 297, 298, 3, 36, 18, 0, 298, 304, 1, 0, 0, 0, 299, 300, 10, 2, 0, 0, 300, 301, 7, 4, 0, 0, 301, 303, 3, 34, 17, 3, 302, 299, 1, 0, 0, 0, 303, 306, 1, 0, 0, 0, 304, 302, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 35, 1, 0, 0, 0, 306, 304, 1, 0, 0, 0, 307, 308, 6, 18, -1, 0, 308, 309, 3, 40, 20, 0, 309, 315, 1, 0, 0, 0, 310, 311, 10, 2, 0, 0, 311, 312, 7, 5, 0, 0, 312, 314, 3, 36, 18, 3, 313, 310, 1, 0, 0, 0, 314, 317, 1, 0, 0, 0, 315, 313, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 37, 1, 0, 0, 0, 317, 315, 1, 0, 0, 0, 318, 319, 6, 19, -1, 0, 319, 320, 3, 42, 21, 0, 320, 326, 1, 0, 0, 0, 321, 322, 10, 2, 0, 0, 322, 323, 7, 5, 0, 0, 323, 325, 3, 38, 19, 3, 324, 321, 1, 0, 0, 0, 325, 328, 1, 0, 0, 0, 326, 324, 1, 0, 0, 0, 326, 327, 1, 0, 0, 0, 327, 39, 1, 0, 0, 0, 328, 326, 1, 0, 0, 0, 329, 330, 7, 4, 0, 0, 330, 337, 3, 40, 20, 0, 331, 333, 3, 44, 22, 0, 332, 331, 1, 0, 0, 0, 333, 334, 1, 0, 0, 0, 334, 332, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 337, 1, 0, 0, 0, 336, 329, 1, 0, 0, 0, 336, 332, 1, 0, 0, 0, 337, 41, 1, 0, 0, 0, 338, 339, 7, 4, 0, 0, 339, 348, 3, 42, 21, 0, 340, 344, 3, 44, 22, 0, 341, 343, 3, 46, 23, 0, 342, 341, 1, 0, 0, 0, 343, 346, 1, 0, 0, 0, 344, 342, 1, 0, 0, 0, 344, 345, 1, 0, 0, 0, 345, 348, 1, 0, 0, 0, 346, 344, 1, 0, 0, 0, 347, 338, 1, 0, 0, 0, 347, 340, 1, 0, 0, 0, 348, 43, 1, 0, 0, 0, 349, 353, 3, 56, 28, 0, 350, 352, 3, 48, 24, 0, 351, 350, 1, 0, 0, 0, 352, 355, 1, 0, 0, 0, 353, 351, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 45, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, 360, 3, 58, 29, 0, 357, 359, 3, 48, 24, 0, 358, 357, 1, 0, 0, 0, 359, 362, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 47, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 363, 367, 5, 189, 0, 0, 364, 367, 3, 50, 25, 0, 365, 367, 3, 4, 2, 0, 366, 363, 1, 0, 0, 0, 366, 364, 1, 0, 0, 0, 366, 365, 1, 0, 0, 0, 367, 49, 1, 0, 0, 0, 368, 374, 5, 65, 0, 0, 369, 375, 3, 54, 27, 0, 370, 375, 3, 52, 26, 0, 371, 372, 3, 54, 27, 0, 372, 373, 3, 52, 26, 0, 373, 375, 1, 0, 0, 0, 374, 369, 1, 0, 0, 0, 374, 370, 1, 0, 0, 0, 374, 371, 1, 0, 0, 0, 375, 51, 1, 0, 0, 0, 376, 377, 5, 167, 0, 0, 377, 380, 5, 55, 0, 0, 378, 381, 3, 32, 16, 0, 379, 381, 3, 30, 15, 0, 380, 378, 1, 0, 0, 0, 380, 379, 1, 0, 0, 0, 381, 382, 1, 0, 0, 0, 382, 383, 5, 56, 0, 0, 383, 53, 1, 0, 0, 0, 384, 385, 5, 168, 0, 0, 385, 388, 5, 55, 0, 0, 386, 389, 3, 32, 16, 0, 387, 389, 3, 30, 15, 0, 388, 386, 1, 0, 0, 0, 388, 387, 1, 0, 0, 0, 389, 390, 1, 0, 0, 0, 390, 391, 5, 56, 0, 0, 391, 55, 1, 0, 0, 0, 392, 393, 6, 28, -1, 0, 393, 394, 3, 60, 30, 0, 394, 409, 1, 0, 0, 0, 395, 396, 10, 2, 0, 0, 396, 402, 5, 168, 0, 0, 397, 403, 3, 80, 40, 0, 398, 399, 5, 55, 0, 0, 399, 400, 3, 32, 16, 0, 400, 401, 5, 56, 0, 0, 401, 403, 1, 0, 0, 0, 402, 397, 1, 0, 0, 0, 402, 398, 1, 0, 0, 0, 403, 405, 1, 0, 0, 0, 404, 406, 3, 118, 59, 0, 405, 404, 1, 0, 0, 0, 405, 406, 1, 0, 0, 0, 406, 408, 1, 0, 0, 0, 407, 395, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 407, 1, 0, 0, 0, 409, 410, 1, 0, 0, 0, 410, 57, 1, 0, 0, 0, 411, 409, 1, 0, 0, 0, 412, 413, 6, 29, -1, 0, 413, 414, 3, 62, 31, 0, 414, 429, 1, 0, 0, 0, 415, 416, 10, 2, 0, 0, 416, 422, 5, 168, 0, 0, 417, 423, 3, 80, 40, 0, 418, 419, 5, 55, 0, 0, 419, 420, 3, 32, 16, 0, 420, 421, 5, 56, 0, 0, 421, 423, 1, 0, 0, 0, 422, 417, 1, 0, 0, 0, 422, 418, 1, 0, 0, 0, 423, 425, 1, 0, 0, 0, 424, 426, 3, 118, 59, 0, 425, 424, 1, 0, 0, 0, 425, 426, 1, 0, 0, 0, 426, 428, 1, 0, 0, 0, 427, 415, 1, 0, 0, 0, 428, 431, 1, 0, 0, 0, 429, 427, 1, 0, 0, 0, 429, 430, 1, 0, 0, 0, 430, 59, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 432, 444, 3, 64, 32, 0, 433, 444, 3, 66, 33, 0, 434, 444, 3, 68, 34, 0, 435, 444, 3, 70, 35, 0, 436, 444, 3, 72, 36, 0, 437, 444, 3, 102, 51, 0, 438, 444, 3, 80, 40, 0, 439, 444, 3, 86, 43, 0, 440, 444, 3, 88, 44, 0, 441, 444, 3, 18, 9, 0, 442, 444, 3, 20, 10, 0, 443, 432, 1, 0, 0, 0, 443, 433, 1, 0, 0, 0, 443, 434, 1, 0, 0, 0, 443, 435, 1, 0, 0, 0, 443, 436, 1, 0, 0, 0, 443, 437, 1, 0, 0, 0, 443, 438, 1, 0, 0, 0, 443, 439, 1, 0, 0, 0, 443, 440, 1, 0, 0, 0, 443, 441, 1, 0, 0, 0, 443, 442, 1, 0, 0, 0, 444, 61, 1, 0, 0, 0, 445, 456, 3, 64, 32, 0, 446, 456, 3, 66, 33, 0, 447, 456, 3, 68, 34, 0, 448, 456, 3, 70, 35, 0, 449, 456, 3, 72, 36, 0, 450, 456, 3, 80, 40, 0, 451, 456, 3, 86, 43, 0, 452, 456, 3, 88, 44, 0, 453, 456, 3, 18, 9, 0, 454, 456, 3, 20, 10, 0, 455, 445, 1, 0, 0, 0, 455, 446, 1, 0, 0, 0, 455, 447, 1, 0, 0, 0, 455, 448, 1, 0, 0, 0, 455, 449, 1, 0, 0, 0, 455, 450, 1, 0, 0, 0, 455, 451, 1, 0, 0, 0, 455, 452, 1, 0, 0, 0, 455, 453, 1, 0, 0, 0, 455, 454, 1, 0, 0, 0, 456, 63, 1, 0, 0, 0, 457, 458, 5, 51, 0, 0, 458, 459, 3, 32, 16, 0, 459, 460, 5, 52, 0, 0, 460, 570, 1, 0, 0, 0, 461, 462, 5, 53, 0, 0, 462, 463, 3, 32, 16, 0, 463, 464, 5, 54, 0, 0, 464, 570, 1, 0, 0, 0, 465, 466, 5, 55, 0, 0, 466, 467, 3, 32, 16, 0, 467, 468, 5, 56, 0, 0, 468, 570, 1, 0, 0, 0, 469, 470, 5, 57, 0, 0, 470, 471, 3, 32, 16, 0, 471, 472, 5, 58, 0, 0, 472, 570, 1, 0, 0, 0, 473, 474, 5, 59, 0, 0, 474, 475, 3, 32, 16, 0, 475, 476, 5, 60, 0, 0, 476, 570, 1, 0, 0, 0, 477, 478, 5, 61, 0, 0, 478, 479, 3, 32, 16, 0, 479, 480, 5, 62, 0, 0, 480, 570, 1, 0, 0, 0, 481, 482, 5, 63, 0, 0, 482, 483, 3, 32, 16, 0, 483, 484, 5, 64, 0, 0, 484, 570, 1, 0, 0, 0, 485, 486, 5, 78, 0, 0, 486, 487, 5, 51, 0, 0, 487, 488, 3, 32, 16, 0, 488, 489, 5, 79, 0, 0, 489, 490, 5, 52, 0, 0, 490, 570, 1, 0, 0, 0, 491, 492, 5, 78, 0, 0, 492, 493, 5, 53, 0, 0, 493, 494, 3, 32, 16, 0, 494, 495, 5, 79, 0, 0, 495, 496, 5, 54, 0, 0, 496, 570, 1, 0, 0, 0, 497, 498, 5, 78, 0, 0, 498, 499, 5, 55, 0, 0, 499, 500, 3, 32, 16, 0, 500, 501, 5, 79, 0, 0, 501, 502, 5, 56, 0, 0, 502, 570, 1, 0, 0, 0, 503, 504, 5, 78, 0, 0, 504, 505, 5, 57, 0, 0, 505, 506, 3, 32, 16, 0, 506, 507, 5, 79, 0, 0, 507, 508, 5, 58, 0, 0, 508, 570, 1, 0, 0, 0, 509, 510, 5, 78, 0, 0, 510, 511, 5, 59, 0, 0, 511, 512, 3, 32, 16, 0, 512, 513, 5, 79, 0, 0, 513, 514, 5, 60, 0, 0, 514, 570, 1, 0, 0, 0, 515, 516, 5, 78, 0, 0, 516, 517, 5, 61, 0, 0, 517, 518, 3, 32, 16, 0, 518, 519, 5, 79, 0, 0, 519, 520, 5, 62, 0, 0, 520, 570, 1, 0, 0, 0, 521, 522, 5, 78, 0, 0, 522, 523, 5, 63, 0, 0, 523, 524, 3, 32, 16, 0, 524, 525, 5, 79, 0, 0, 525, 526, 5, 64, 0, 0, 526, 570, 1, 0, 0, 0, 527, 528, 5, 80, 0, 0, 528, 529, 5, 51, 0, 0, 529, 530, 3, 32, 16, 0, 530, 531, 5, 81, 0, 0, 531, 532, 5, 52, 0, 0, 532, 570, 1, 0, 0, 0, 533, 534, 5, 80, 0, 0, 534, 535, 5, 53, 0, 0, 535, 536, 3, 32, 16, 0, 536, 537, 5, 81, 0, 0, 537, 538, 5, 54, 0, 0, 538, 570, 1, 0, 0, 0, 539, 540, 5, 80, 0, 0, 540, 541, 5, 55, 0, 0, 541, 542, 3, 32, 16, 0, 542, 543, 5, 81, 0, 0, 543, 544, 5, 56, 0, 0, 544, 570, 1, 0, 0, 0, 545, 546, 5, 80, 0, 0, 546, 547, 5, 57, 0, 0, 547, 548, 3, 32, 16, 0, 548, 549, 5, 81, 0, 0, 549, 550, 5, 58, 0, 0, 550, 570, 1, 0, 0, 0, 551, 552, 5, 80, 0, 0, 552, 553, 5, 59, 0, 0, 553, 554, 3, 32, 16, 0, 554, 555, 5, 81, 0, 0, 555, 556, 5, 60, 0, 0, 556, 570, 1, 0, 0, 0, 557, 558, 5, 80, 0, 0, 558, 559, 5, 61, 0, 0, 559, 560, 3, 32, 16, 0, 560, 561, 5, 81, 0, 0, 561, 562, 5, 62, 0, 0, 562, 570, 1, 0, 0, 0, 563, 564, 5, 80, 0, 0, 564, 565, 5, 63, 0, 0, 565, 566, 3, 32, 16, 0, 566, 567, 5, 81, 0, 0, 567, 568, 5, 64, 0, 0, 568, 570, 1, 0, 0, 0, 569, 457, 1, 0, 0, 0, 569, 461, 1, 0, 0, 0, 569, 465, 1, 0, 0, 0, 569, 469, 1, 0, 0, 0, 569, 473, 1, 0, 0, 0, 569, 477, 1, 0, 0, 0, 569, 481, 1, 0, 0, 0, 569, 485, 1, 0, 0, 0, 569, 491, 1, 0, 0, 0, 569, 497, 1, 0, 0, 0, 569, 503, 1, 0, 0, 0, 569, 509, 1, 0, 0, 0, 569, 515, 1, 0, 0, 0, 569, 521, 1, 0, 0, 0, 569, 527, 1, 0, 0, 0, 569, 533, 1, 0, 0, 0, 569, 539, 1, 0, 0, 0, 569, 545, 1, 0, 0, 0, 569, 551, 1, 0, 0, 0, 569, 557, 1, 0, 0, 0, 569, 563, 1, 0, 0, 0, 570, 65, 1, 0, 0, 0, 571, 572, 5, 69, 0, 0, 572, 573, 3, 32, 16, 0, 573, 574, 5, 69, 0, 0, 574, 588, 1, 0, 0, 0, 575, 576, 5, 78, 0, 0, 576, 577, 5, 69, 0, 0, 577, 578, 3, 32, 16, 0, 578, 579, 5, 79, 0, 0, 579, 580, 5, 69, 0, 0, 580, 588, 1, 0, 0, 0, 581, 582, 5, 80, 0, 0, 582, 583, 5, 69, 0, 0, 583, 584, 3, 32, 16, 0, 584, 585, 5, 81, 0, 0, 585, 586, 5, 69, 0, 0, 586, 588, 1, 0, 0, 0, 587, 571, 1, 0, 0, 0, 587, 575, 1, 0, 0, 0, 587, 581, 1, 0, 0, 0, 588, 67, 1, 0, 0, 0, 589, 590, 5, 65, 0, 0, 590, 591, 3, 32, 16, 0, 591, 592, 5, 65, 0, 0, 592, 638, 1, 0, 0, 0, 593, 594, 5, 66, 0, 0, 594, 595, 3, 32, 16, 0, 595, 596, 5, 67, 0, 0, 596, 638, 1, 0, 0, 0, 597, 598, 5, 68, 0, 0, 598, 599, 3, 32, 16, 0, 599, 600, 5, 68, 0, 0, 600, 638, 1, 0, 0, 0, 601, 602, 5, 78, 0, 0, 602, 603, 5, 65, 0, 0, 603, 604, 3, 32, 16, 0, 604, 605, 5, 79, 0, 0, 605, 606, 5, 65, 0, 0, 606, 638, 1, 0, 0, 0, 607, 608, 5, 78, 0, 0, 608, 609, 5, 66, 0, 0, 609, 610, 3, 32, 16, 0, 610, 611, 5, 79, 0, 0, 611, 612, 5, 67, 0, 0, 612, 638, 1, 0, 0, 0, 613, 614, 5, 78, 0, 0, 614, 615, 5, 68, 0, 0, 615, 616, 3, 32, 16, 0, 616, 617, 5, 79, 0, 0, 617, 618, 5, 68, 0, 0, 618, 638, 1, 0, 0, 0, 619, 620, 5, 80, 0, 0, 620, 621, 5, 65, 0, 0, 621, 622, 3, 32, 16, 0, 622, 623, 5, 81, 0, 0, 623, 624, 5, 65, 0, 0, 624, 638, 1, 0, 0, 0, 625, 626, 5, 80, 0, 0, 626, 627, 5, 66, 0, 0, 627, 628, 3, 32, 16, 0, 628, 629, 5, 81, 0, 0, 629, 630, 5, 67, 0, 0, 630, 638, 1, 0, 0, 0, 631, 632, 5, 80, 0, 0, 632, 633, 5, 68, 0, 0, 633, 634, 3, 32, 16, 0, 634, 635, 5, 81, 0, 0, 635, 636, 5, 68, 0, 0, 636, 638, 1, 0, 0, 0, 637, 589, 1, 0, 0, 0, 637, 593, 1, 0, 0, 0, 637, 597, 1, 0, 0, 0, 637, 601, 1, 0, 0, 0, 637, 607, 1, 0, 0, 0, 637, 613, 1, 0, 0, 0, 637, 619, 1, 0, 0, 0, 637, 625, 1, 0, 0, 0, 637, 631, 1, 0, 0, 0, 638, 69, 1, 0, 0, 0, 639, 640, 5, 70, 0, 0, 640, 641, 3, 32, 16, 0, 641, 642, 5, 71, 0, 0, 642, 672, 1, 0, 0, 0, 643, 644, 5, 72, 0, 0, 644, 645, 3, 32, 16, 0, 645, 646, 5, 73, 0, 0, 646, 672, 1, 0, 0, 0, 647, 648, 5, 78, 0, 0, 648, 649, 5, 70, 0, 0, 649, 650, 3, 32, 16, 0, 650, 651, 5, 79, 0, 0, 651, 652, 5, 71, 0, 0, 652, 672, 1, 0, 0, 0, 653, 654, 5, 78, 0, 0, 654, 655, 5, 72, 0, 0, 655, 656, 3, 32, 16, 0, 656, 657, 5, 79, 0, 0, 657, 658, 5, 73, 0, 0, 658, 672, 1, 0, 0, 0, 659, 660, 5, 80, 0, 0, 660, 661, 5, 70, 0, 0, 661, 662, 3, 32, 16, 0, 662, 663, 5, 81, 0, 0, 663, 664, 5, 71, 0, 0, 664, 672, 1, 0, 0, 0, 665, 666, 5, 80, 0, 0, 666, 667, 5, 72, 0, 0, 667, 668, 3, 32, 16, 0, 668, 669, 5, 81, 0, 0, 669, 670, 5, 73, 0, 0, 670, 672, 1, 0, 0, 0, 671, 639, 1, 0, 0, 0, 671, 643, 1, 0, 0, 0, 671, 647, 1, 0, 0, 0, 671, 653, 1, 0, 0, 0, 671, 659, 1, 0, 0, 0, 671, 665, 1, 0, 0, 0, 672, 71, 1, 0, 0, 0, 673, 674, 5, 74, 0, 0, 674, 675, 3, 32, 16, 0, 675, 676, 5, 75, 0, 0, 676, 706, 1, 0, 0, 0, 677, 678, 5, 76, 0, 0, 678, 679, 3, 32, 16, 0, 679, 680, 5, 77, 0, 0, 680, 706, 1, 0, 0, 0, 681, 682, 5, 78, 0, 0, 682, 683, 5, 74, 0, 0, 683, 684, 3, 32, 16, 0, 684, 685, 5, 79, 0, 0, 685, 686, 5, 75, 0, 0, 686, 706, 1, 0, 0, 0, 687, 688, 5, 78, 0, 0, 688, 689, 5, 76, 0, 0, 689, 690, 3, 32, 16, 0, 690, 691, 5, 79, 0, 0, 691, 692, 5, 77, 0, 0, 692, 706, 1, 0, 0, 0, 693, 694, 5, 80, 0, 0, 694, 695, 5, 74, 0, 0, 695, 696, 3, 32, 16, 0, 696, 697, 5, 81, 0, 0, 697, 698, 5, 75, 0, 0, 698, 706, 1, 0, 0, 0, 699, 700, 5, 80, 0, 0, 700, 701, 5, 76, 0, 0, 701, 702, 3, 32, 16, 0, 702, 703, 5, 81, 0, 0, 703, 704, 5, 77, 0, 0, 704, 706, 1, 0, 0, 0, 705, 673, 1, 0, 0, 0, 705, 677, 1, 0, 0, 0, 705, 681, 1, 0, 0, 0, 705, 687, 1, 0, 0, 0, 705, 693, 1, 0, 0, 0, 705, 699, 1, 0, 0, 0, 706, 73, 1, 0, 0, 0, 707, 708, 3, 0, 0, 0, 708, 709, 5, 55, 0, 0, 709, 710, 3, 32, 16, 0, 710, 711, 5, 56, 0, 0, 711, 75, 1, 0, 0, 0, 712, 717, 5, 176, 0, 0, 713, 717, 5, 191, 0, 0, 714, 717, 5, 192, 0, 0, 715, 717, 3, 74, 37, 0, 716, 712, 1, 0, 0, 0, 716, 713, 1, 0, 0, 0, 716, 714, 1, 0, 0, 0, 716, 715, 1, 0, 0, 0, 717, 719, 1, 0, 0, 0, 718, 720, 3, 118, 59, 0, 719, 718, 1, 0, 0, 0, 719, 720, 1, 0, 0, 0, 720, 77, 1, 0, 0, 0, 721, 726, 5, 176, 0, 0, 722, 726, 5, 191, 0, 0, 723, 726, 5, 192, 0, 0, 724, 726, 3, 74, 37, 0, 725, 721, 1, 0, 0, 0, 725, 722, 1, 0, 0, 0, 725, 723, 1, 0, 0, 0, 725, 724, 1, 0, 0, 0, 726, 735, 1, 0, 0, 0, 727, 728, 3, 120, 60, 0, 728, 729, 3, 118, 59, 0, 729, 736, 1, 0, 0, 0, 730, 731, 3, 118, 59, 0, 731, 732, 3, 120, 60, 0, 732, 736, 1, 0, 0, 0, 733, 736, 3, 118, 59, 0, 734, 736, 3, 120, 60, 0, 735, 727, 1, 0, 0, 0, 735, 730, 1, 0, 0, 0, 735, 733, 1, 0, 0, 0, 735, 734, 1, 0, 0, 0, 735, 736, 1, 0, 0, 0, 736, 79, 1, 0, 0, 0, 737, 746, 3, 78, 39, 0, 738, 746, 5, 193, 0, 0, 739, 746, 5, 179, 0, 0, 740, 746, 5, 190, 0, 0, 741, 746, 5, 180, 0, 0, 742, 746, 5, 173, 0, 0, 743, 746, 3, 82, 41, 0, 744, 746, 5, 194, 0, 0, 745, 737, 1, 0, 0, 0, 745, 738, 1, 0, 0, 0, 745, 739, 1, 0, 0, 0, 745, 740, 1, 0, 0, 0, 745, 741, 1, 0, 0, 0, 745, 742, 1, 0, 0, 0, 745, 743, 1, 0, 0, 0, 745, 744, 1, 0, 0, 0, 746, 81, 1, 0, 0, 0, 747, 748, 5, 154, 0, 0, 748, 749, 5, 55, 0, 0, 749, 750, 3, 84, 42, 0, 750, 751, 5, 56, 0, 0, 751, 83, 1, 0, 0, 0, 752, 754, 7, 6, 0, 0, 753, 752, 1, 0, 0, 0, 754, 755, 1, 0, 0, 0, 755, 753, 1, 0, 0, 0, 755, 756, 1, 0, 0, 0, 756, 85, 1, 0, 0, 0, 757, 758, 5, 150, 0, 0, 758, 759, 5, 55, 0, 0, 759, 760, 3, 32, 16, 0, 760, 761, 5, 56, 0, 0, 761, 762, 5, 55, 0, 0, 762, 763, 3, 32, 16, 0, 763, 764, 5, 56, 0, 0, 764, 87, 1, 0, 0, 0, 765, 766, 5, 55, 0, 0, 766, 767, 3, 32, 16, 0, 767, 768, 5, 152, 0, 0, 768, 769, 3, 32, 16, 0, 769, 770, 5, 56, 0, 0, 770, 780, 1, 0, 0, 0, 771, 772, 5, 151, 0, 0, 772, 773, 5, 55, 0, 0, 773, 774, 3, 32, 16, 0, 774, 775, 5, 56, 0, 0, 775, 776, 5, 55, 0, 0, 776, 777, 3, 32, 16, 0, 777, 778, 5, 56, 0, 0, 778, 780, 1, 0, 0, 0, 779, 765, 1, 0, 0, 0, 779, 771, 1, 0, 0, 0, 780, 89, 1, 0, 0, 0, 781, 782, 7, 7, 0, 0, 782, 91, 1, 0, 0, 0, 783, 784, 7, 8, 0, 0, 784, 93, 1, 0, 0, 0, 785, 786, 7, 9, 0, 0, 786, 95, 1, 0, 0, 0, 787, 788, 7, 10, 0, 0, 788, 97, 1, 0, 0, 0, 789, 796, 3, 90, 45, 0, 790, 791, 5, 155, 0, 0, 791, 792, 5, 55, 0, 0, 792, 793, 3, 94, 47, 0, 793, 794, 5, 56, 0, 0, 794, 796, 1, 0, 0, 0, 795, 789, 1, 0, 0, 0, 795, 790, 1, 0, 0, 0, 796, 99, 1, 0, 0, 0, 797, 804, 3, 92, 46, 0, 798, 799, 5, 155, 0, 0, 799, 800, 5, 55, 0, 0, 800, 801, 3, 96, 48, 0, 801, 802, 5, 56, 0, 0, 802, 804, 1, 0, 0, 0, 803, 797, 1, 0, 0, 0, 803, 798, 1, 0, 0, 0, 804, 101, 1, 0, 0, 0, 805, 818, 3, 98, 49, 0, 806, 808, 3, 118, 59, 0, 807, 806, 1, 0, 0, 0, 807, 808, 1, 0, 0, 0, 808, 810, 1, 0, 0, 0, 809, 811, 3, 120, 60, 0, 810, 809, 1, 0, 0, 0, 810, 811, 1, 0, 0, 0, 811, 819, 1, 0, 0, 0, 812, 814, 3, 120, 60, 0, 813, 812, 1, 0, 0, 0, 813, 814, 1, 0, 0, 0, 814, 816, 1, 0, 0, 0, 815, 817, 3, 118, 59, 0, 816, 815, 1, 0, 0, 0, 816, 817, 1, 0, 0, 0, 817, 819, 1, 0, 0, 0, 818, 807, 1, 0, 0, 0, 818, 813, 1, 0, 0, 0, 819, 841, 1, 0, 0, 0, 820, 822, 5, 78, 0, 0, 821, 820, 1, 0, 0, 0, 821, 822, 1, 0, 0, 0, 822, 823, 1, 0, 0, 0, 823, 824, 5, 51, 0, 0, 824, 826, 3, 110, 55, 0, 825, 827, 5, 79, 0, 0, 826, 825, 1, 0, 0, 0, 826, 827, 1, 0, 0, 0, 827, 828, 1, 0, 0, 0, 828, 829, 5, 52, 0, 0, 829, 842, 1, 0, 0, 0, 830, 832, 5, 80, 0, 0, 831, 830, 1, 0, 0, 0, 831, 832, 1, 0, 0, 0, 832, 833, 1, 0, 0, 0, 833, 834, 5, 51, 0, 0, 834, 836, 3, 110, 55, 0, 835, 837, 5, 81, 0, 0, 836, 835, 1, 0, 0, 0, 836, 837, 1, 0, 0, 0, 837, 838, 1, 0, 0, 0, 838, 839, 5, 52, 0, 0, 839, 842, 1, 0, 0, 0, 840, 842, 3, 112, 56, 0, 841, 821, 1, 0, 0, 0, 841, 831, 1, 0, 0, 0, 841, 840, 1, 0, 0, 0, 842, 972, 1, 0, 0, 0, 843, 856, 3, 100, 50, 0, 844, 846, 3, 118, 59, 0, 845, 844, 1, 0, 0, 0, 845, 846, 1, 0, 0, 0, 846, 848, 1, 0, 0, 0, 847, 849, 3, 120, 60, 0, 848, 847, 1, 0, 0, 0, 848, 849, 1, 0, 0, 0, 849, 857, 1, 0, 0, 0, 850, 852, 3, 120, 60, 0, 851, 850, 1, 0, 0, 0, 851, 852, 1, 0, 0, 0, 852, 854, 1, 0, 0, 0, 853, 855, 3, 118, 59, 0, 854, 853, 1, 0, 0, 0, 854, 855, 1, 0, 0, 0, 855, 857, 1, 0, 0, 0, 856, 845, 1, 0, 0, 0, 856, 851, 1, 0, 0, 0, 857, 879, 1, 0, 0, 0, 858, 860, 5, 78, 0, 0, 859, 858, 1, 0, 0, 0, 859, 860, 1, 0, 0, 0, 860, 861, 1, 0, 0, 0, 861, 862, 5, 51, 0, 0, 862, 864, 3, 114, 57, 0, 863, 865, 5, 79, 0, 0, 864, 863, 1, 0, 0, 0, 864, 865, 1, 0, 0, 0, 865, 866, 1, 0, 0, 0, 866, 867, 5, 52, 0, 0, 867, 880, 1, 0, 0, 0, 868, 870, 5, 80, 0, 0, 869, 868, 1, 0, 0, 0, 869, 870, 1, 0, 0, 0, 870, 871, 1, 0, 0, 0, 871, 872, 5, 51, 0, 0, 872, 874, 3, 114, 57, 0, 873, 875, 5, 81, 0, 0, 874, 873, 1, 0, 0, 0, 874, 875, 1, 0, 0, 0, 875, 876, 1, 0, 0, 0, 876, 877, 5, 52, 0, 0, 877, 880, 1, 0, 0, 0, 878, 880, 3, 116, 58, 0, 879, 859, 1, 0, 0, 0, 879, 869, 1, 0, 0, 0, 879, 878, 1, 0, 0, 0, 880, 972, 1, 0, 0, 0, 881, 883, 3, 76, 38, 0, 882, 884, 3, 120, 60, 0, 883, 882, 1, 0, 0, 0, 883, 884, 1, 0, 0, 0, 884, 886, 1, 0, 0, 0, 885, 887, 5, 78, 0, 0, 886, 885, 1, 0, 0, 0, 886, 887, 1, 0, 0, 0, 887, 888, 1, 0, 0, 0, 888, 889, 7, 11, 0, 0, 889, 890, 3, 106, 53, 0, 890, 892, 7, 12, 0, 0, 891, 893, 5, 79, 0, 0, 892, 891, 1, 0, 0, 0, 892, 893, 1, 0, 0, 0, 893, 972, 1, 0, 0, 0, 894, 896, 3, 76, 38, 0, 895, 897, 3, 120, 60, 0, 896, 895, 1, 0, 0, 0, 896, 897, 1, 0, 0, 0, 897, 898, 1, 0, 0, 0, 898, 900, 5, 55, 0, 0, 899, 901, 5, 78, 0, 0, 900, 899, 1, 0, 0, 0, 900, 901, 1, 0, 0, 0, 901, 902, 1, 0, 0, 0, 902, 903, 7, 11, 0, 0, 903, 904, 3, 106, 53, 0, 904, 906, 7, 12, 0, 0, 905, 907, 5, 79, 0, 0, 906, 905, 1, 0, 0, 0, 906, 907, 1, 0, 0, 0, 907, 908, 1, 0, 0, 0, 908, 909, 5, 56, 0, 0, 909, 972, 1, 0, 0, 0, 910, 931, 5, 84, 0, 0, 911, 912, 3, 118, 59, 0, 912, 913, 3, 120, 60, 0, 913, 932, 1, 0, 0, 0, 914, 915, 3, 120, 60, 0, 915, 916, 3, 118, 59, 0, 916, 932, 1, 0, 0, 0, 917, 918, 5, 167, 0, 0, 918, 919, 5, 55, 0, 0, 919, 920, 5, 56, 0, 0, 920, 921, 1, 0, 0, 0, 921, 922, 5, 168, 0, 0, 922, 923, 5, 55, 0, 0, 923, 932, 5, 56, 0, 0, 924, 925, 5, 168, 0, 0, 925, 926, 5, 55, 0, 0, 926, 927, 5, 56, 0, 0, 927, 928, 1, 0, 0, 0, 928, 929, 5, 167, 0, 0, 929, 930, 5, 55, 0, 0, 930, 932, 5, 56, 0, 0, 931, 911, 1, 0, 0, 0, 931, 914, 1, 0, 0, 0, 931, 917, 1, 0, 0, 0, 931, 924, 1, 0, 0, 0, 931, 932, 1, 0, 0, 0, 932, 939, 1, 0, 0, 0, 933, 935, 3, 34, 17, 0, 934, 933, 1, 0, 0, 0, 934, 935, 1, 0, 0, 0, 935, 936, 1, 0, 0, 0, 936, 940, 5, 173, 0, 0, 937, 940, 3, 86, 43, 0, 938, 940, 3, 34, 17, 0, 939, 934, 1, 0, 0, 0, 939, 937, 1, 0, 0, 0, 939, 938, 1, 0, 0, 0, 940, 972, 1, 0, 0, 0, 941, 946, 5, 121, 0, 0, 942, 943, 5, 61, 0, 0, 943, 944, 3, 32, 16, 0, 944, 945, 5, 62, 0, 0, 945, 947, 1, 0, 0, 0, 946, 942, 1, 0, 0, 0, 946, 947, 1, 0, 0, 0, 947, 948, 1, 0, 0, 0, 948, 949, 5, 55, 0, 0, 949, 950, 3, 32, 16, 0, 950, 951, 5, 56, 0, 0, 951, 972, 1, 0, 0, 0, 952, 959, 7, 13, 0, 0, 953, 954, 3, 122, 61, 0, 954, 955, 3, 120, 60, 0, 955, 960, 1, 0, 0, 0, 956, 957, 3, 120, 60, 0, 957, 958, 3, 122, 61, 0, 958, 960, 1, 0, 0, 0, 959, 953, 1, 0, 0, 0, 959, 956, 1, 0, 0, 0, 960, 961, 1, 0, 0, 0, 961, 962, 3, 36, 18, 0, 962, 972, 1, 0, 0, 0, 963, 964, 5, 82, 0, 0, 964, 965, 3, 108, 54, 0, 965, 966, 3, 36, 18, 0, 966, 972, 1, 0, 0, 0, 967, 969, 5, 174, 0, 0, 968, 970, 3, 120, 60, 0, 969, 968, 1, 0, 0, 0, 969, 970, 1, 0, 0, 0, 970, 972, 1, 0, 0, 0, 971, 805, 1, 0, 0, 0, 971, 843, 1, 0, 0, 0, 971, 881, 1, 0, 0, 0, 971, 894, 1, 0, 0, 0, 971, 910, 1, 0, 0, 0, 971, 941, 1, 0, 0, 0, 971, 952, 1, 0, 0, 0, 971, 963, 1, 0, 0, 0, 971, 967, 1, 0, 0, 0, 972, 103, 1, 0, 0, 0, 973, 974, 3, 32, 16, 0, 974, 975, 5, 171, 0, 0, 975, 976, 3, 104, 52, 0, 976, 979, 1, 0, 0, 0, 977, 979, 3, 32, 16, 0, 978, 973, 1, 0, 0, 0, 978, 977, 1, 0, 0, 0, 979, 105, 1, 0, 0, 0, 980, 989, 3, 80, 40, 0, 981, 982, 3, 32, 16, 0, 982, 983, 5, 171, 0, 0, 983, 989, 1, 0, 0, 0, 984, 985, 3, 32, 16, 0, 985, 986, 5, 171, 0, 0, 986, 987, 3, 104, 52, 0, 987, 989, 1, 0, 0, 0, 988, 980, 1, 0, 0, 0, 988, 981, 1, 0, 0, 0, 988, 984, 1, 0, 0, 0, 989, 107, 1, 0, 0, 0, 990, 991, 5, 167, 0, 0, 991, 992, 5, 55, 0, 0, 992, 993, 7, 14, 0, 0, 993, 994, 5, 83, 0, 0, 994, 999, 3, 32, 16, 0, 995, 996, 5, 168, 0, 0, 996, 997, 5, 55, 0, 0, 997, 998, 7, 4, 0, 0, 998, 1000, 5, 56, 0, 0, 999, 995, 1, 0, 0, 0, 999, 1000, 1, 0, 0, 0, 1000, 1001, 1, 0, 0, 0, 1001, 1002, 5, 56, 0, 0, 1002, 109, 1, 0, 0, 0, 1003, 1004, 3, 32, 16, 0, 1004, 111, 1, 0, 0, 0, 1005, 1006, 3, 38, 19, 0, 1006, 113, 1, 0, 0, 0, 1007, 1013, 3, 32, 16, 0, 1008, 1009, 3, 32, 16, 0, 1009, 1010, 5, 171, 0, 0, 1010, 1011, 3, 114, 57, 0, 1011, 1013, 1, 0, 0, 0, 1012, 1007, 1, 0, 0, 0, 1012, 1008, 1, 0, 0, 0, 1013, 115, 1, 0, 0, 0, 1014, 1015, 3, 38, 19, 0, 1015, 117, 1, 0, 0, 0, 1016, 1025, 5, 167, 0, 0, 1017, 1026, 3, 80, 40, 0, 1018, 1021, 5, 55, 0, 0, 1019, 1022, 3, 32, 16, 0, 1020, 1022, 3, 104, 52, 0, 1021, 1019, 1, 0, 0, 0, 1021, 1020, 1, 0, 0, 0, 1022, 1023, 1, 0, 0, 0, 1023, 1024, 5, 56, 0, 0, 1024, 1026, 1, 0, 0, 0, 1025, 1017, 1, 0, 0, 0, 1025, 1018, 1, 0, 0, 0, 1026, 119, 1, 0, 0, 0, 1027, 1033, 5, 168, 0, 0, 1028, 1034, 3, 80, 40, 0, 1029, 1030, 5, 55, 0, 0, 1030, 1031, 3, 32, 16, 0, 1031, 1032, 5, 56, 0, 0, 1032, 1034, 1, 0, 0, 0, 1033, 1028, 1, 0, 0, 0, 1033, 1029, 1, 0, 0, 0, 1034, 121, 1, 0, 0, 0, 1035, 1036, 5, 167, 0, 0, 1036, 1037, 5, 55, 0, 0, 1037, 1038, 3, 30, 15, 0, 1038, 1039, 5, 56, 0, 0, 1039, 123, 1, 0, 0, 0, 1040, 1041, 5, 167, 0, 0, 1041, 1042, 5, 55, 0, 0, 1042, 1043, 3, 30, 15, 0, 1043, 1044, 5, 56, 0, 0, 1044, 125, 1, 0, 0, 0, 92, 130, 140, 146, 160, 167, 176, 180, 188, 194, 202, 206, 215, 226, 266, 275, 285, 288, 304, 315, 326, 334, 336, 344, 347, 353, 360, 366, 374, 380, 388, 402, 405, 409, 422, 425, 429, 443, 455, 569, 587, 637, 671, 705, 716, 719, 725, 735, 745, 755, 779, 795, 803, 807, 810, 813, 816, 818, 821, 826, 831, 836, 841, 845, 848, 851, 854, 856, 859, 864, 869, 874, 879, 883, 886, 892, 896, 900, 906, 931, 934, 939, 946, 959, 969, 971, 978, 988, 999, 1012, 1021, 1025, 1033]
latex2sympy/gen/PS.tokens ADDED
@@ -0,0 +1,357 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ T__0=1
2
+ T__1=2
3
+ T__2=3
4
+ T__3=4
5
+ T__4=5
6
+ T__5=6
7
+ T__6=7
8
+ T__7=8
9
+ T__8=9
10
+ T__9=10
11
+ T__10=11
12
+ T__11=12
13
+ T__12=13
14
+ T__13=14
15
+ T__14=15
16
+ T__15=16
17
+ T__16=17
18
+ T__17=18
19
+ T__18=19
20
+ T__19=20
21
+ T__20=21
22
+ T__21=22
23
+ T__22=23
24
+ T__23=24
25
+ T__24=25
26
+ T__25=26
27
+ T__26=27
28
+ T__27=28
29
+ T__28=29
30
+ T__29=30
31
+ T__30=31
32
+ T__31=32
33
+ T__32=33
34
+ T__33=34
35
+ T__34=35
36
+ T__35=36
37
+ T__36=37
38
+ T__37=38
39
+ T__38=39
40
+ T__39=40
41
+ T__40=41
42
+ T__41=42
43
+ T__42=43
44
+ T__43=44
45
+ WS=45
46
+ DOLLAR_SIGN=46
47
+ ADD=47
48
+ SUB=48
49
+ MUL=49
50
+ DIV=50
51
+ L_PAREN=51
52
+ R_PAREN=52
53
+ L_GROUP=53
54
+ R_GROUP=54
55
+ L_BRACE=55
56
+ R_BRACE=56
57
+ L_BRACE_VISUAL=57
58
+ R_BRACE_VISUAL=58
59
+ L_BRACE_CMD=59
60
+ R_BRACE_CMD=60
61
+ L_BRACKET=61
62
+ R_BRACKET=62
63
+ L_BRACK=63
64
+ R_BRACK=64
65
+ BAR=65
66
+ L_VERT=66
67
+ R_VERT=67
68
+ VERT=68
69
+ NORM=69
70
+ L_FLOOR=70
71
+ R_FLOOR=71
72
+ LL_CORNER=72
73
+ LR_CORNER=73
74
+ L_CEIL=74
75
+ R_CEIL=75
76
+ UL_CORNER=76
77
+ UR_CORNER=77
78
+ L_LEFT=78
79
+ R_RIGHT=79
80
+ ML_LEFT=80
81
+ MR_RIGHT=81
82
+ FUNC_LIM=82
83
+ LIM_APPROACH_SYM=83
84
+ FUNC_INT=84
85
+ FUNC_SUM=85
86
+ FUNC_PROD=86
87
+ FUNC_LOG=87
88
+ FUNC_LN=88
89
+ FUNC_EXP=89
90
+ FUNC_SIN=90
91
+ FUNC_COS=91
92
+ FUNC_TAN=92
93
+ FUNC_CSC=93
94
+ FUNC_SEC=94
95
+ FUNC_COT=95
96
+ FUNC_ARCSIN=96
97
+ FUNC_ARCCOS=97
98
+ FUNC_ARCTAN=98
99
+ FUNC_ARCCSC=99
100
+ FUNC_ARCSEC=100
101
+ FUNC_ARCCOT=101
102
+ FUNC_SINH=102
103
+ FUNC_COSH=103
104
+ FUNC_TANH=104
105
+ FUNC_ARSINH=105
106
+ FUNC_ARCOSH=106
107
+ FUNC_ARTANH=107
108
+ FUNC_ARCSINH=108
109
+ FUNC_ARCCOSH=109
110
+ FUNC_ARCTANH=110
111
+ FUNC_ARSINH_NAME=111
112
+ FUNC_ARCSINH_NAME=112
113
+ FUNC_ARCOSH_NAME=113
114
+ FUNC_ARCCOSH_NAME=114
115
+ FUNC_ARTANH_NAME=115
116
+ FUNC_ARCTANH_NAME=116
117
+ FUNC_GCD_NAME=117
118
+ FUNC_LCM_NAME=118
119
+ FUNC_FLOOR_NAME=119
120
+ FUNC_CEIL_NAME=120
121
+ FUNC_SQRT=121
122
+ FUNC_GCD=122
123
+ FUNC_LCM=123
124
+ FUNC_FLOOR=124
125
+ FUNC_CEIL=125
126
+ FUNC_MAX=126
127
+ FUNC_MIN=127
128
+ FUNC_DET=128
129
+ FUNC_EYE_NAME=129
130
+ FUNC_ZEROS_NAME=130
131
+ FUNC_ONES_NAME=131
132
+ FUNC_COLS_NAME=132
133
+ FUNC_ROWS_NAME=133
134
+ FUNC_DIAG_NAME=134
135
+ FUNC_NORM_NAME=135
136
+ FUNC_RANK_NAME=136
137
+ FUNC_TRACE_NAME=137
138
+ FUNC_RREF_NAME=138
139
+ FUNC_HSTACK_NAME=139
140
+ FUNC_VSTACK_NAME=140
141
+ FUNC_ORTHOGONALIZE_NAME=141
142
+ FUNC_NULLSPACE_NAME=142
143
+ FUNC_DIAGONALIZE_NAME=143
144
+ FUNC_EIGENVALS_NAME=144
145
+ FUNC_EIGENVECTORS_NAME=145
146
+ FUNC_SVD_NAME=146
147
+ CMD_TIMES=147
148
+ CMD_CDOT=148
149
+ CMD_DIV=149
150
+ CMD_FRAC=150
151
+ CMD_BINOM=151
152
+ CMD_CHOOSE=152
153
+ CMD_MOD=153
154
+ CMD_MATHIT=154
155
+ CMD_OPERATORNAME=155
156
+ MATRIX_TYPE_MATRIX=156
157
+ MATRIX_TYPE_PMATRIX=157
158
+ MATRIX_TYPE_BMATRIX=158
159
+ MATRIX_TYPE_DET=159
160
+ MATRIX_TYPES=160
161
+ CMD_MATRIX_START=161
162
+ CMD_MATRIX_END=162
163
+ CMD_DET_START=163
164
+ CMD_DET_END=164
165
+ MATRIX_DEL_COL=165
166
+ MATRIX_DEL_ROW=166
167
+ UNDERSCORE=167
168
+ CARET=168
169
+ COLON=169
170
+ SEMICOLON=170
171
+ COMMA=171
172
+ PERIOD=172
173
+ DIFFERENTIAL=173
174
+ EXP_E=174
175
+ E_NOTATION_E=175
176
+ LETTER_NO_E=176
177
+ MATRIX_XRIGHTARROW=177
178
+ TRANSFORM_EXCHANGE=178
179
+ NUMBER=179
180
+ E_NOTATION=180
181
+ IN=181
182
+ ASSIGNMENT=182
183
+ EQUAL=183
184
+ LT=184
185
+ LTE=185
186
+ GT=186
187
+ GTE=187
188
+ UNEQUAL=188
189
+ BANG=189
190
+ PERCENT_NUMBER=190
191
+ GREEK_CMD=191
192
+ OTHER_SYMBOL_CMD=192
193
+ SYMBOL=193
194
+ VARIABLE=194
195
+ '\\acute'=1
196
+ '\\bar'=2
197
+ '\\overline'=3
198
+ '\\breve'=4
199
+ '\\check'=5
200
+ '\\widecheck'=6
201
+ '\\dot'=7
202
+ '\\ddot'=8
203
+ '\\grave'=9
204
+ '\\hat'=10
205
+ '\\tilde'=11
206
+ '\\widetilde'=12
207
+ '\\vec'=13
208
+ '\\overrightarrow'=14
209
+ '\\bm'=15
210
+ '\\boldsymbol'=16
211
+ '\\text'=17
212
+ '\\textit'=18
213
+ '\\mathbb'=19
214
+ '\\mathbin'=20
215
+ '\\mathbf'=21
216
+ '\\mathcal'=22
217
+ '\\mathclap'=23
218
+ '\\mathclose'=24
219
+ '\\mathellipsis'=25
220
+ '\\mathfrak'=26
221
+ '\\mathinner'=27
222
+ '\\mathnormal'=28
223
+ '\\mathop'=29
224
+ '\\mathopen'=30
225
+ '\\mathord'=31
226
+ '\\mathpunct'=32
227
+ '\\mathrel'=33
228
+ '\\mathring'=34
229
+ '\\mathrlap'=35
230
+ '\\mathrm'=36
231
+ '\\mathscr'=37
232
+ '\\mathsf'=38
233
+ '\\mathsterling'=39
234
+ '\\mathtt'=40
235
+ '^T'=41
236
+ '^{T}'=42
237
+ '^{\\top}'=43
238
+ '\''=44
239
+ '\\$'=46
240
+ '+'=47
241
+ '-'=48
242
+ '*'=49
243
+ '('=51
244
+ ')'=52
245
+ '\\lgroup'=53
246
+ '\\rgroup'=54
247
+ '{'=55
248
+ '}'=56
249
+ '\\{'=57
250
+ '\\}'=58
251
+ '\\lbrace'=59
252
+ '\\rbrace'=60
253
+ '['=61
254
+ ']'=62
255
+ '\\lbrack'=63
256
+ '\\rbrack'=64
257
+ '|'=65
258
+ '\\lvert'=66
259
+ '\\rvert'=67
260
+ '\\vert'=68
261
+ '\\|'=69
262
+ '\\lfloor'=70
263
+ '\\rfloor'=71
264
+ '\\llcorner'=72
265
+ '\\lrcorner'=73
266
+ '\\lceil'=74
267
+ '\\rceil'=75
268
+ '\\ulcorner'=76
269
+ '\\urcorner'=77
270
+ '\\left'=78
271
+ '\\right'=79
272
+ '\\mleft'=80
273
+ '\\mright'=81
274
+ '\\lim'=82
275
+ '\\int'=84
276
+ '\\sum'=85
277
+ '\\prod'=86
278
+ '\\log'=87
279
+ '\\ln'=88
280
+ '\\exp'=89
281
+ '\\sin'=90
282
+ '\\cos'=91
283
+ '\\tan'=92
284
+ '\\csc'=93
285
+ '\\sec'=94
286
+ '\\cot'=95
287
+ '\\arcsin'=96
288
+ '\\arccos'=97
289
+ '\\arctan'=98
290
+ '\\arccsc'=99
291
+ '\\arcsec'=100
292
+ '\\arccot'=101
293
+ '\\sinh'=102
294
+ '\\cosh'=103
295
+ '\\tanh'=104
296
+ '\\arsinh'=105
297
+ '\\arcosh'=106
298
+ '\\artanh'=107
299
+ '\\arcsinh'=108
300
+ '\\arccosh'=109
301
+ '\\arctanh'=110
302
+ 'arsinh'=111
303
+ 'arcsinh'=112
304
+ 'arcosh'=113
305
+ 'arccosh'=114
306
+ 'artanh'=115
307
+ 'arctanh'=116
308
+ 'gcd'=117
309
+ 'lcm'=118
310
+ 'floor'=119
311
+ 'ceil'=120
312
+ '\\sqrt'=121
313
+ '\\gcd'=122
314
+ '\\lcm'=123
315
+ '\\floor'=124
316
+ '\\ceil'=125
317
+ '\\max'=126
318
+ '\\min'=127
319
+ '\\det'=128
320
+ 'eye'=129
321
+ 'zeros'=130
322
+ 'ones'=131
323
+ 'cols'=132
324
+ 'rows'=133
325
+ 'diag'=134
326
+ 'norm'=135
327
+ 'rank'=136
328
+ 'rref'=138
329
+ 'hstack'=139
330
+ 'vstack'=140
331
+ 'nullspace'=142
332
+ '\\times'=147
333
+ '\\cdot'=148
334
+ '\\div'=149
335
+ '\\frac'=150
336
+ '\\choose'=152
337
+ '\\mod'=153
338
+ '\\mathit'=154
339
+ '\\operatorname'=155
340
+ 'matrix'=156
341
+ 'pmatrix'=157
342
+ 'bmatrix'=158
343
+ 'vmatrix'=159
344
+ '&'=165
345
+ '\\\\'=166
346
+ '_'=167
347
+ '^'=168
348
+ ':'=169
349
+ ';'=170
350
+ ','=171
351
+ '.'=172
352
+ 'E'=175
353
+ '\\in'=181
354
+ '='=182
355
+ '<'=184
356
+ '>'=186
357
+ '!'=189
latex2sympy/gen/PSLexer.interp ADDED
The diff for this file is too large to render. See raw diff
 
latex2sympy/gen/PSLexer.py ADDED
The diff for this file is too large to render. See raw diff
 
latex2sympy/gen/PSLexer.tokens ADDED
@@ -0,0 +1,357 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ T__0=1
2
+ T__1=2
3
+ T__2=3
4
+ T__3=4
5
+ T__4=5
6
+ T__5=6
7
+ T__6=7
8
+ T__7=8
9
+ T__8=9
10
+ T__9=10
11
+ T__10=11
12
+ T__11=12
13
+ T__12=13
14
+ T__13=14
15
+ T__14=15
16
+ T__15=16
17
+ T__16=17
18
+ T__17=18
19
+ T__18=19
20
+ T__19=20
21
+ T__20=21
22
+ T__21=22
23
+ T__22=23
24
+ T__23=24
25
+ T__24=25
26
+ T__25=26
27
+ T__26=27
28
+ T__27=28
29
+ T__28=29
30
+ T__29=30
31
+ T__30=31
32
+ T__31=32
33
+ T__32=33
34
+ T__33=34
35
+ T__34=35
36
+ T__35=36
37
+ T__36=37
38
+ T__37=38
39
+ T__38=39
40
+ T__39=40
41
+ T__40=41
42
+ T__41=42
43
+ T__42=43
44
+ T__43=44
45
+ WS=45
46
+ DOLLAR_SIGN=46
47
+ ADD=47
48
+ SUB=48
49
+ MUL=49
50
+ DIV=50
51
+ L_PAREN=51
52
+ R_PAREN=52
53
+ L_GROUP=53
54
+ R_GROUP=54
55
+ L_BRACE=55
56
+ R_BRACE=56
57
+ L_BRACE_VISUAL=57
58
+ R_BRACE_VISUAL=58
59
+ L_BRACE_CMD=59
60
+ R_BRACE_CMD=60
61
+ L_BRACKET=61
62
+ R_BRACKET=62
63
+ L_BRACK=63
64
+ R_BRACK=64
65
+ BAR=65
66
+ L_VERT=66
67
+ R_VERT=67
68
+ VERT=68
69
+ NORM=69
70
+ L_FLOOR=70
71
+ R_FLOOR=71
72
+ LL_CORNER=72
73
+ LR_CORNER=73
74
+ L_CEIL=74
75
+ R_CEIL=75
76
+ UL_CORNER=76
77
+ UR_CORNER=77
78
+ L_LEFT=78
79
+ R_RIGHT=79
80
+ ML_LEFT=80
81
+ MR_RIGHT=81
82
+ FUNC_LIM=82
83
+ LIM_APPROACH_SYM=83
84
+ FUNC_INT=84
85
+ FUNC_SUM=85
86
+ FUNC_PROD=86
87
+ FUNC_LOG=87
88
+ FUNC_LN=88
89
+ FUNC_EXP=89
90
+ FUNC_SIN=90
91
+ FUNC_COS=91
92
+ FUNC_TAN=92
93
+ FUNC_CSC=93
94
+ FUNC_SEC=94
95
+ FUNC_COT=95
96
+ FUNC_ARCSIN=96
97
+ FUNC_ARCCOS=97
98
+ FUNC_ARCTAN=98
99
+ FUNC_ARCCSC=99
100
+ FUNC_ARCSEC=100
101
+ FUNC_ARCCOT=101
102
+ FUNC_SINH=102
103
+ FUNC_COSH=103
104
+ FUNC_TANH=104
105
+ FUNC_ARSINH=105
106
+ FUNC_ARCOSH=106
107
+ FUNC_ARTANH=107
108
+ FUNC_ARCSINH=108
109
+ FUNC_ARCCOSH=109
110
+ FUNC_ARCTANH=110
111
+ FUNC_ARSINH_NAME=111
112
+ FUNC_ARCSINH_NAME=112
113
+ FUNC_ARCOSH_NAME=113
114
+ FUNC_ARCCOSH_NAME=114
115
+ FUNC_ARTANH_NAME=115
116
+ FUNC_ARCTANH_NAME=116
117
+ FUNC_GCD_NAME=117
118
+ FUNC_LCM_NAME=118
119
+ FUNC_FLOOR_NAME=119
120
+ FUNC_CEIL_NAME=120
121
+ FUNC_SQRT=121
122
+ FUNC_GCD=122
123
+ FUNC_LCM=123
124
+ FUNC_FLOOR=124
125
+ FUNC_CEIL=125
126
+ FUNC_MAX=126
127
+ FUNC_MIN=127
128
+ FUNC_DET=128
129
+ FUNC_EYE_NAME=129
130
+ FUNC_ZEROS_NAME=130
131
+ FUNC_ONES_NAME=131
132
+ FUNC_COLS_NAME=132
133
+ FUNC_ROWS_NAME=133
134
+ FUNC_DIAG_NAME=134
135
+ FUNC_NORM_NAME=135
136
+ FUNC_RANK_NAME=136
137
+ FUNC_TRACE_NAME=137
138
+ FUNC_RREF_NAME=138
139
+ FUNC_HSTACK_NAME=139
140
+ FUNC_VSTACK_NAME=140
141
+ FUNC_ORTHOGONALIZE_NAME=141
142
+ FUNC_NULLSPACE_NAME=142
143
+ FUNC_DIAGONALIZE_NAME=143
144
+ FUNC_EIGENVALS_NAME=144
145
+ FUNC_EIGENVECTORS_NAME=145
146
+ FUNC_SVD_NAME=146
147
+ CMD_TIMES=147
148
+ CMD_CDOT=148
149
+ CMD_DIV=149
150
+ CMD_FRAC=150
151
+ CMD_BINOM=151
152
+ CMD_CHOOSE=152
153
+ CMD_MOD=153
154
+ CMD_MATHIT=154
155
+ CMD_OPERATORNAME=155
156
+ MATRIX_TYPE_MATRIX=156
157
+ MATRIX_TYPE_PMATRIX=157
158
+ MATRIX_TYPE_BMATRIX=158
159
+ MATRIX_TYPE_DET=159
160
+ MATRIX_TYPES=160
161
+ CMD_MATRIX_START=161
162
+ CMD_MATRIX_END=162
163
+ CMD_DET_START=163
164
+ CMD_DET_END=164
165
+ MATRIX_DEL_COL=165
166
+ MATRIX_DEL_ROW=166
167
+ UNDERSCORE=167
168
+ CARET=168
169
+ COLON=169
170
+ SEMICOLON=170
171
+ COMMA=171
172
+ PERIOD=172
173
+ DIFFERENTIAL=173
174
+ EXP_E=174
175
+ E_NOTATION_E=175
176
+ LETTER_NO_E=176
177
+ MATRIX_XRIGHTARROW=177
178
+ TRANSFORM_EXCHANGE=178
179
+ NUMBER=179
180
+ E_NOTATION=180
181
+ IN=181
182
+ ASSIGNMENT=182
183
+ EQUAL=183
184
+ LT=184
185
+ LTE=185
186
+ GT=186
187
+ GTE=187
188
+ UNEQUAL=188
189
+ BANG=189
190
+ PERCENT_NUMBER=190
191
+ GREEK_CMD=191
192
+ OTHER_SYMBOL_CMD=192
193
+ SYMBOL=193
194
+ VARIABLE=194
195
+ '\\acute'=1
196
+ '\\bar'=2
197
+ '\\overline'=3
198
+ '\\breve'=4
199
+ '\\check'=5
200
+ '\\widecheck'=6
201
+ '\\dot'=7
202
+ '\\ddot'=8
203
+ '\\grave'=9
204
+ '\\hat'=10
205
+ '\\tilde'=11
206
+ '\\widetilde'=12
207
+ '\\vec'=13
208
+ '\\overrightarrow'=14
209
+ '\\bm'=15
210
+ '\\boldsymbol'=16
211
+ '\\text'=17
212
+ '\\textit'=18
213
+ '\\mathbb'=19
214
+ '\\mathbin'=20
215
+ '\\mathbf'=21
216
+ '\\mathcal'=22
217
+ '\\mathclap'=23
218
+ '\\mathclose'=24
219
+ '\\mathellipsis'=25
220
+ '\\mathfrak'=26
221
+ '\\mathinner'=27
222
+ '\\mathnormal'=28
223
+ '\\mathop'=29
224
+ '\\mathopen'=30
225
+ '\\mathord'=31
226
+ '\\mathpunct'=32
227
+ '\\mathrel'=33
228
+ '\\mathring'=34
229
+ '\\mathrlap'=35
230
+ '\\mathrm'=36
231
+ '\\mathscr'=37
232
+ '\\mathsf'=38
233
+ '\\mathsterling'=39
234
+ '\\mathtt'=40
235
+ '^T'=41
236
+ '^{T}'=42
237
+ '^{\\top}'=43
238
+ '\''=44
239
+ '\\$'=46
240
+ '+'=47
241
+ '-'=48
242
+ '*'=49
243
+ '('=51
244
+ ')'=52
245
+ '\\lgroup'=53
246
+ '\\rgroup'=54
247
+ '{'=55
248
+ '}'=56
249
+ '\\{'=57
250
+ '\\}'=58
251
+ '\\lbrace'=59
252
+ '\\rbrace'=60
253
+ '['=61
254
+ ']'=62
255
+ '\\lbrack'=63
256
+ '\\rbrack'=64
257
+ '|'=65
258
+ '\\lvert'=66
259
+ '\\rvert'=67
260
+ '\\vert'=68
261
+ '\\|'=69
262
+ '\\lfloor'=70
263
+ '\\rfloor'=71
264
+ '\\llcorner'=72
265
+ '\\lrcorner'=73
266
+ '\\lceil'=74
267
+ '\\rceil'=75
268
+ '\\ulcorner'=76
269
+ '\\urcorner'=77
270
+ '\\left'=78
271
+ '\\right'=79
272
+ '\\mleft'=80
273
+ '\\mright'=81
274
+ '\\lim'=82
275
+ '\\int'=84
276
+ '\\sum'=85
277
+ '\\prod'=86
278
+ '\\log'=87
279
+ '\\ln'=88
280
+ '\\exp'=89
281
+ '\\sin'=90
282
+ '\\cos'=91
283
+ '\\tan'=92
284
+ '\\csc'=93
285
+ '\\sec'=94
286
+ '\\cot'=95
287
+ '\\arcsin'=96
288
+ '\\arccos'=97
289
+ '\\arctan'=98
290
+ '\\arccsc'=99
291
+ '\\arcsec'=100
292
+ '\\arccot'=101
293
+ '\\sinh'=102
294
+ '\\cosh'=103
295
+ '\\tanh'=104
296
+ '\\arsinh'=105
297
+ '\\arcosh'=106
298
+ '\\artanh'=107
299
+ '\\arcsinh'=108
300
+ '\\arccosh'=109
301
+ '\\arctanh'=110
302
+ 'arsinh'=111
303
+ 'arcsinh'=112
304
+ 'arcosh'=113
305
+ 'arccosh'=114
306
+ 'artanh'=115
307
+ 'arctanh'=116
308
+ 'gcd'=117
309
+ 'lcm'=118
310
+ 'floor'=119
311
+ 'ceil'=120
312
+ '\\sqrt'=121
313
+ '\\gcd'=122
314
+ '\\lcm'=123
315
+ '\\floor'=124
316
+ '\\ceil'=125
317
+ '\\max'=126
318
+ '\\min'=127
319
+ '\\det'=128
320
+ 'eye'=129
321
+ 'zeros'=130
322
+ 'ones'=131
323
+ 'cols'=132
324
+ 'rows'=133
325
+ 'diag'=134
326
+ 'norm'=135
327
+ 'rank'=136
328
+ 'rref'=138
329
+ 'hstack'=139
330
+ 'vstack'=140
331
+ 'nullspace'=142
332
+ '\\times'=147
333
+ '\\cdot'=148
334
+ '\\div'=149
335
+ '\\frac'=150
336
+ '\\choose'=152
337
+ '\\mod'=153
338
+ '\\mathit'=154
339
+ '\\operatorname'=155
340
+ 'matrix'=156
341
+ 'pmatrix'=157
342
+ 'bmatrix'=158
343
+ 'vmatrix'=159
344
+ '&'=165
345
+ '\\\\'=166
346
+ '_'=167
347
+ '^'=168
348
+ ':'=169
349
+ ';'=170
350
+ ','=171
351
+ '.'=172
352
+ 'E'=175
353
+ '\\in'=181
354
+ '='=182
355
+ '<'=184
356
+ '>'=186
357
+ '!'=189
latex2sympy/gen/PSListener.py ADDED
@@ -0,0 +1,573 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated from PS.g4 by ANTLR 4.11.1
2
+ from antlr4 import *
3
+
4
+ # This class defines a complete listener for a parse tree produced by PSParser.
5
+
6
+
7
+ class PSListener(ParseTreeListener):
8
+
9
+ # Enter a parse tree produced by PSParser#accent_symbol.
10
+ def enterAccent_symbol(self, ctx):
11
+ pass
12
+
13
+ # Exit a parse tree produced by PSParser#accent_symbol.
14
+ def exitAccent_symbol(self, ctx):
15
+ pass
16
+
17
+ # Enter a parse tree produced by PSParser#math.
18
+
19
+ def enterMath(self, ctx):
20
+ pass
21
+
22
+ # Exit a parse tree produced by PSParser#math.
23
+ def exitMath(self, ctx):
24
+ pass
25
+
26
+ # Enter a parse tree produced by PSParser#transpose.
27
+
28
+ def enterTranspose(self, ctx):
29
+ pass
30
+
31
+ # Exit a parse tree produced by PSParser#transpose.
32
+ def exitTranspose(self, ctx):
33
+ pass
34
+
35
+ # Enter a parse tree produced by PSParser#transform_atom.
36
+
37
+ def enterTransform_atom(self, ctx):
38
+ pass
39
+
40
+ # Exit a parse tree produced by PSParser#transform_atom.
41
+ def exitTransform_atom(self, ctx):
42
+ pass
43
+
44
+ # Enter a parse tree produced by PSParser#transform_scale.
45
+
46
+ def enterTransform_scale(self, ctx):
47
+ pass
48
+
49
+ # Exit a parse tree produced by PSParser#transform_scale.
50
+ def exitTransform_scale(self, ctx):
51
+ pass
52
+
53
+ # Enter a parse tree produced by PSParser#transform_swap.
54
+
55
+ def enterTransform_swap(self, ctx):
56
+ pass
57
+
58
+ # Exit a parse tree produced by PSParser#transform_swap.
59
+ def exitTransform_swap(self, ctx):
60
+ pass
61
+
62
+ # Enter a parse tree produced by PSParser#transform_assignment.
63
+
64
+ def enterTransform_assignment(self, ctx):
65
+ pass
66
+
67
+ # Exit a parse tree produced by PSParser#transform_assignment.
68
+ def exitTransform_assignment(self, ctx):
69
+ pass
70
+
71
+ # Enter a parse tree produced by PSParser#elementary_transform.
72
+
73
+ def enterElementary_transform(self, ctx):
74
+ pass
75
+
76
+ # Exit a parse tree produced by PSParser#elementary_transform.
77
+ def exitElementary_transform(self, ctx):
78
+ pass
79
+
80
+ # Enter a parse tree produced by PSParser#elementary_transforms.
81
+
82
+ def enterElementary_transforms(self, ctx):
83
+ pass
84
+
85
+ # Exit a parse tree produced by PSParser#elementary_transforms.
86
+ def exitElementary_transforms(self, ctx):
87
+ pass
88
+
89
+ # Enter a parse tree produced by PSParser#matrix.
90
+
91
+ def enterMatrix(self, ctx):
92
+ pass
93
+
94
+ # Exit a parse tree produced by PSParser#matrix.
95
+ def exitMatrix(self, ctx):
96
+ pass
97
+
98
+ # Enter a parse tree produced by PSParser#det.
99
+
100
+ def enterDet(self, ctx):
101
+ pass
102
+
103
+ # Exit a parse tree produced by PSParser#det.
104
+ def exitDet(self, ctx):
105
+ pass
106
+
107
+ # Enter a parse tree produced by PSParser#matrix_row.
108
+
109
+ def enterMatrix_row(self, ctx):
110
+ pass
111
+
112
+ # Exit a parse tree produced by PSParser#matrix_row.
113
+ def exitMatrix_row(self, ctx):
114
+ pass
115
+
116
+ # Enter a parse tree produced by PSParser#relation.
117
+
118
+ def enterRelation(self, ctx):
119
+ pass
120
+
121
+ # Exit a parse tree produced by PSParser#relation.
122
+ def exitRelation(self, ctx):
123
+ pass
124
+
125
+ # Enter a parse tree produced by PSParser#relation_list.
126
+
127
+ def enterRelation_list(self, ctx):
128
+ pass
129
+
130
+ # Exit a parse tree produced by PSParser#relation_list.
131
+ def exitRelation_list(self, ctx):
132
+ pass
133
+
134
+ # Enter a parse tree produced by PSParser#relation_list_content.
135
+
136
+ def enterRelation_list_content(self, ctx):
137
+ pass
138
+
139
+ # Exit a parse tree produced by PSParser#relation_list_content.
140
+ def exitRelation_list_content(self, ctx):
141
+ pass
142
+
143
+ # Enter a parse tree produced by PSParser#equality.
144
+
145
+ def enterEquality(self, ctx):
146
+ pass
147
+
148
+ # Exit a parse tree produced by PSParser#equality.
149
+ def exitEquality(self, ctx):
150
+ pass
151
+
152
+ # Enter a parse tree produced by PSParser#expr.
153
+
154
+ def enterExpr(self, ctx):
155
+ pass
156
+
157
+ # Exit a parse tree produced by PSParser#expr.
158
+ def exitExpr(self, ctx):
159
+ pass
160
+
161
+ # Enter a parse tree produced by PSParser#additive.
162
+
163
+ def enterAdditive(self, ctx):
164
+ pass
165
+
166
+ # Exit a parse tree produced by PSParser#additive.
167
+ def exitAdditive(self, ctx):
168
+ pass
169
+
170
+ # Enter a parse tree produced by PSParser#mp.
171
+
172
+ def enterMp(self, ctx):
173
+ pass
174
+
175
+ # Exit a parse tree produced by PSParser#mp.
176
+ def exitMp(self, ctx):
177
+ pass
178
+
179
+ # Enter a parse tree produced by PSParser#mp_nofunc.
180
+
181
+ def enterMp_nofunc(self, ctx):
182
+ pass
183
+
184
+ # Exit a parse tree produced by PSParser#mp_nofunc.
185
+ def exitMp_nofunc(self, ctx):
186
+ pass
187
+
188
+ # Enter a parse tree produced by PSParser#unary.
189
+
190
+ def enterUnary(self, ctx):
191
+ pass
192
+
193
+ # Exit a parse tree produced by PSParser#unary.
194
+ def exitUnary(self, ctx):
195
+ pass
196
+
197
+ # Enter a parse tree produced by PSParser#unary_nofunc.
198
+
199
+ def enterUnary_nofunc(self, ctx):
200
+ pass
201
+
202
+ # Exit a parse tree produced by PSParser#unary_nofunc.
203
+ def exitUnary_nofunc(self, ctx):
204
+ pass
205
+
206
+ # Enter a parse tree produced by PSParser#postfix.
207
+
208
+ def enterPostfix(self, ctx):
209
+ pass
210
+
211
+ # Exit a parse tree produced by PSParser#postfix.
212
+ def exitPostfix(self, ctx):
213
+ pass
214
+
215
+ # Enter a parse tree produced by PSParser#postfix_nofunc.
216
+
217
+ def enterPostfix_nofunc(self, ctx):
218
+ pass
219
+
220
+ # Exit a parse tree produced by PSParser#postfix_nofunc.
221
+ def exitPostfix_nofunc(self, ctx):
222
+ pass
223
+
224
+ # Enter a parse tree produced by PSParser#postfix_op.
225
+
226
+ def enterPostfix_op(self, ctx):
227
+ pass
228
+
229
+ # Exit a parse tree produced by PSParser#postfix_op.
230
+ def exitPostfix_op(self, ctx):
231
+ pass
232
+
233
+ # Enter a parse tree produced by PSParser#eval_at.
234
+
235
+ def enterEval_at(self, ctx):
236
+ pass
237
+
238
+ # Exit a parse tree produced by PSParser#eval_at.
239
+ def exitEval_at(self, ctx):
240
+ pass
241
+
242
+ # Enter a parse tree produced by PSParser#eval_at_sub.
243
+
244
+ def enterEval_at_sub(self, ctx):
245
+ pass
246
+
247
+ # Exit a parse tree produced by PSParser#eval_at_sub.
248
+ def exitEval_at_sub(self, ctx):
249
+ pass
250
+
251
+ # Enter a parse tree produced by PSParser#eval_at_sup.
252
+
253
+ def enterEval_at_sup(self, ctx):
254
+ pass
255
+
256
+ # Exit a parse tree produced by PSParser#eval_at_sup.
257
+ def exitEval_at_sup(self, ctx):
258
+ pass
259
+
260
+ # Enter a parse tree produced by PSParser#exp.
261
+
262
+ def enterExp(self, ctx):
263
+ pass
264
+
265
+ # Exit a parse tree produced by PSParser#exp.
266
+ def exitExp(self, ctx):
267
+ pass
268
+
269
+ # Enter a parse tree produced by PSParser#exp_nofunc.
270
+
271
+ def enterExp_nofunc(self, ctx):
272
+ pass
273
+
274
+ # Exit a parse tree produced by PSParser#exp_nofunc.
275
+ def exitExp_nofunc(self, ctx):
276
+ pass
277
+
278
+ # Enter a parse tree produced by PSParser#comp.
279
+
280
+ def enterComp(self, ctx):
281
+ pass
282
+
283
+ # Exit a parse tree produced by PSParser#comp.
284
+ def exitComp(self, ctx):
285
+ pass
286
+
287
+ # Enter a parse tree produced by PSParser#comp_nofunc.
288
+
289
+ def enterComp_nofunc(self, ctx):
290
+ pass
291
+
292
+ # Exit a parse tree produced by PSParser#comp_nofunc.
293
+ def exitComp_nofunc(self, ctx):
294
+ pass
295
+
296
+ # Enter a parse tree produced by PSParser#group.
297
+
298
+ def enterGroup(self, ctx):
299
+ pass
300
+
301
+ # Exit a parse tree produced by PSParser#group.
302
+ def exitGroup(self, ctx):
303
+ pass
304
+
305
+ # Enter a parse tree produced by PSParser#norm_group.
306
+
307
+ def enterNorm_group(self, ctx):
308
+ pass
309
+
310
+ # Exit a parse tree produced by PSParser#norm_group.
311
+ def exitNorm_group(self, ctx):
312
+ pass
313
+
314
+ # Enter a parse tree produced by PSParser#abs_group.
315
+
316
+ def enterAbs_group(self, ctx):
317
+ pass
318
+
319
+ # Exit a parse tree produced by PSParser#abs_group.
320
+ def exitAbs_group(self, ctx):
321
+ pass
322
+
323
+ # Enter a parse tree produced by PSParser#floor_group.
324
+
325
+ def enterFloor_group(self, ctx):
326
+ pass
327
+
328
+ # Exit a parse tree produced by PSParser#floor_group.
329
+ def exitFloor_group(self, ctx):
330
+ pass
331
+
332
+ # Enter a parse tree produced by PSParser#ceil_group.
333
+
334
+ def enterCeil_group(self, ctx):
335
+ pass
336
+
337
+ # Exit a parse tree produced by PSParser#ceil_group.
338
+ def exitCeil_group(self, ctx):
339
+ pass
340
+
341
+ # Enter a parse tree produced by PSParser#accent.
342
+
343
+ def enterAccent(self, ctx):
344
+ pass
345
+
346
+ # Exit a parse tree produced by PSParser#accent.
347
+ def exitAccent(self, ctx):
348
+ pass
349
+
350
+ # Enter a parse tree produced by PSParser#atom_expr_no_supexpr.
351
+
352
+ def enterAtom_expr_no_supexpr(self, ctx):
353
+ pass
354
+
355
+ # Exit a parse tree produced by PSParser#atom_expr_no_supexpr.
356
+ def exitAtom_expr_no_supexpr(self, ctx):
357
+ pass
358
+
359
+ # Enter a parse tree produced by PSParser#atom_expr.
360
+
361
+ def enterAtom_expr(self, ctx):
362
+ pass
363
+
364
+ # Exit a parse tree produced by PSParser#atom_expr.
365
+ def exitAtom_expr(self, ctx):
366
+ pass
367
+
368
+ # Enter a parse tree produced by PSParser#atom.
369
+
370
+ def enterAtom(self, ctx):
371
+ pass
372
+
373
+ # Exit a parse tree produced by PSParser#atom.
374
+ def exitAtom(self, ctx):
375
+ pass
376
+
377
+ # Enter a parse tree produced by PSParser#mathit.
378
+
379
+ def enterMathit(self, ctx):
380
+ pass
381
+
382
+ # Exit a parse tree produced by PSParser#mathit.
383
+ def exitMathit(self, ctx):
384
+ pass
385
+
386
+ # Enter a parse tree produced by PSParser#mathit_text.
387
+
388
+ def enterMathit_text(self, ctx):
389
+ pass
390
+
391
+ # Exit a parse tree produced by PSParser#mathit_text.
392
+ def exitMathit_text(self, ctx):
393
+ pass
394
+
395
+ # Enter a parse tree produced by PSParser#frac.
396
+
397
+ def enterFrac(self, ctx):
398
+ pass
399
+
400
+ # Exit a parse tree produced by PSParser#frac.
401
+ def exitFrac(self, ctx):
402
+ pass
403
+
404
+ # Enter a parse tree produced by PSParser#binom.
405
+
406
+ def enterBinom(self, ctx):
407
+ pass
408
+
409
+ # Exit a parse tree produced by PSParser#binom.
410
+ def exitBinom(self, ctx):
411
+ pass
412
+
413
+ # Enter a parse tree produced by PSParser#func_normal_functions_single_arg.
414
+
415
+ def enterFunc_normal_functions_single_arg(self, ctx):
416
+ pass
417
+
418
+ # Exit a parse tree produced by PSParser#func_normal_functions_single_arg.
419
+ def exitFunc_normal_functions_single_arg(self, ctx):
420
+ pass
421
+
422
+ # Enter a parse tree produced by PSParser#func_normal_functions_multi_arg.
423
+
424
+ def enterFunc_normal_functions_multi_arg(self, ctx):
425
+ pass
426
+
427
+ # Exit a parse tree produced by PSParser#func_normal_functions_multi_arg.
428
+ def exitFunc_normal_functions_multi_arg(self, ctx):
429
+ pass
430
+
431
+ # Enter a parse tree produced by PSParser#func_operator_names_single_arg.
432
+
433
+ def enterFunc_operator_names_single_arg(self, ctx):
434
+ pass
435
+
436
+ # Exit a parse tree produced by PSParser#func_operator_names_single_arg.
437
+ def exitFunc_operator_names_single_arg(self, ctx):
438
+ pass
439
+
440
+ # Enter a parse tree produced by PSParser#func_operator_names_multi_arg.
441
+
442
+ def enterFunc_operator_names_multi_arg(self, ctx):
443
+ pass
444
+
445
+ # Exit a parse tree produced by PSParser#func_operator_names_multi_arg.
446
+ def exitFunc_operator_names_multi_arg(self, ctx):
447
+ pass
448
+
449
+ # Enter a parse tree produced by PSParser#func_normal_single_arg.
450
+
451
+ def enterFunc_normal_single_arg(self, ctx):
452
+ pass
453
+
454
+ # Exit a parse tree produced by PSParser#func_normal_single_arg.
455
+ def exitFunc_normal_single_arg(self, ctx):
456
+ pass
457
+
458
+ # Enter a parse tree produced by PSParser#func_normal_multi_arg.
459
+
460
+ def enterFunc_normal_multi_arg(self, ctx):
461
+ pass
462
+
463
+ # Exit a parse tree produced by PSParser#func_normal_multi_arg.
464
+ def exitFunc_normal_multi_arg(self, ctx):
465
+ pass
466
+
467
+ # Enter a parse tree produced by PSParser#func.
468
+
469
+ def enterFunc(self, ctx):
470
+ pass
471
+
472
+ # Exit a parse tree produced by PSParser#func.
473
+ def exitFunc(self, ctx):
474
+ pass
475
+
476
+ # Enter a parse tree produced by PSParser#args.
477
+
478
+ def enterArgs(self, ctx):
479
+ pass
480
+
481
+ # Exit a parse tree produced by PSParser#args.
482
+ def exitArgs(self, ctx):
483
+ pass
484
+
485
+ # Enter a parse tree produced by PSParser#func_common_args.
486
+
487
+ def enterFunc_common_args(self, ctx):
488
+ pass
489
+
490
+ # Exit a parse tree produced by PSParser#func_common_args.
491
+ def exitFunc_common_args(self, ctx):
492
+ pass
493
+
494
+ # Enter a parse tree produced by PSParser#limit_sub.
495
+
496
+ def enterLimit_sub(self, ctx):
497
+ pass
498
+
499
+ # Exit a parse tree produced by PSParser#limit_sub.
500
+ def exitLimit_sub(self, ctx):
501
+ pass
502
+
503
+ # Enter a parse tree produced by PSParser#func_single_arg.
504
+
505
+ def enterFunc_single_arg(self, ctx):
506
+ pass
507
+
508
+ # Exit a parse tree produced by PSParser#func_single_arg.
509
+ def exitFunc_single_arg(self, ctx):
510
+ pass
511
+
512
+ # Enter a parse tree produced by PSParser#func_single_arg_noparens.
513
+
514
+ def enterFunc_single_arg_noparens(self, ctx):
515
+ pass
516
+
517
+ # Exit a parse tree produced by PSParser#func_single_arg_noparens.
518
+ def exitFunc_single_arg_noparens(self, ctx):
519
+ pass
520
+
521
+ # Enter a parse tree produced by PSParser#func_multi_arg.
522
+
523
+ def enterFunc_multi_arg(self, ctx):
524
+ pass
525
+
526
+ # Exit a parse tree produced by PSParser#func_multi_arg.
527
+ def exitFunc_multi_arg(self, ctx):
528
+ pass
529
+
530
+ # Enter a parse tree produced by PSParser#func_multi_arg_noparens.
531
+
532
+ def enterFunc_multi_arg_noparens(self, ctx):
533
+ pass
534
+
535
+ # Exit a parse tree produced by PSParser#func_multi_arg_noparens.
536
+ def exitFunc_multi_arg_noparens(self, ctx):
537
+ pass
538
+
539
+ # Enter a parse tree produced by PSParser#subexpr.
540
+
541
+ def enterSubexpr(self, ctx):
542
+ pass
543
+
544
+ # Exit a parse tree produced by PSParser#subexpr.
545
+ def exitSubexpr(self, ctx):
546
+ pass
547
+
548
+ # Enter a parse tree produced by PSParser#supexpr.
549
+
550
+ def enterSupexpr(self, ctx):
551
+ pass
552
+
553
+ # Exit a parse tree produced by PSParser#supexpr.
554
+ def exitSupexpr(self, ctx):
555
+ pass
556
+
557
+ # Enter a parse tree produced by PSParser#subeq.
558
+
559
+ def enterSubeq(self, ctx):
560
+ pass
561
+
562
+ # Exit a parse tree produced by PSParser#subeq.
563
+ def exitSubeq(self, ctx):
564
+ pass
565
+
566
+ # Enter a parse tree produced by PSParser#supeq.
567
+
568
+ def enterSupeq(self, ctx):
569
+ pass
570
+
571
+ # Exit a parse tree produced by PSParser#supeq.
572
+ def exitSupeq(self, ctx):
573
+ pass
latex2sympy/gen/PSParser.py ADDED
The diff for this file is too large to render. See raw diff
 
latex2sympy/gen/__init__.py ADDED
File without changes
latex2sympy/icon.png ADDED
latex2sympy/latex2sympy2.py ADDED
@@ -0,0 +1,1162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sympy
2
+ import re
3
+ from sympy import matrix_symbols, simplify, factor, expand, apart, expand_trig
4
+ from antlr4 import InputStream, CommonTokenStream
5
+ from antlr4.error.ErrorListener import ErrorListener
6
+
7
+ try:
8
+ from gen.PSParser import PSParser
9
+ from gen.PSLexer import PSLexer
10
+ from gen.PSListener import PSListener
11
+ except Exception:
12
+ from .gen.PSParser import PSParser
13
+ from .gen.PSLexer import PSLexer
14
+ from .gen.PSListener import PSListener
15
+
16
+ from sympy.printing.str import StrPrinter
17
+
18
+ from sympy.parsing.sympy_parser import parse_expr
19
+
20
+ import hashlib
21
+
22
+ is_real = None
23
+
24
+ frac_type = r'\frac'
25
+
26
+ variances = {}
27
+ var = {}
28
+
29
+ VARIABLE_VALUES = {}
30
+
31
+
32
+ def set_real(value):
33
+ global is_real
34
+ is_real = value
35
+
36
+
37
+ def set_variances(vars):
38
+ global variances
39
+ variances = vars
40
+ global var
41
+ var = {}
42
+ for variance in vars:
43
+ var[str(variance)] = vars[variance]
44
+
45
+
46
+ def latex2sympy(sympy: str, variable_values={}):
47
+ # record frac
48
+ global frac_type
49
+ if sympy.find(r'\frac') != -1:
50
+ frac_type = r'\frac'
51
+ if sympy.find(r'\dfrac') != -1:
52
+ frac_type = r'\dfrac'
53
+ if sympy.find(r'\tfrac') != -1:
54
+ frac_type = r'\tfrac'
55
+ sympy = sympy.replace(r'\dfrac', r'\frac')
56
+ sympy = sympy.replace(r'\tfrac', r'\frac')
57
+ # Translate Transpose
58
+ sympy = sympy.replace(r'\mathrm{T}', 'T', -1)
59
+ # Translate Derivative
60
+ sympy = sympy.replace(r'\mathrm{d}', 'd', -1).replace(r'{\rm d}', 'd', -1)
61
+ # Translate Matrix
62
+ sympy = sympy.replace(r'\left[\begin{matrix}', r'\begin{bmatrix}', -1).replace(r'\end{matrix}\right]', r'\end{bmatrix}', -1)
63
+ # Translate Permutation
64
+ sympy = re.sub(r"\(([a-zA-Z0-9+\-*/\\ ]+?)\)_{([a-zA-Z0-9+\-*/\\ ]+?)}", r"\\frac{(\1)!}{((\1)-(\2))!}", sympy)
65
+ # Remove \displaystyle
66
+ sympy = sympy.replace(r'\displaystyle', ' ', -1)
67
+ # Remove \quad
68
+ sympy = sympy.replace(r'\quad', ' ', -1).replace(r'\qquad', ' ', -1).replace(r'~', ' ', -1).replace(r'\,', ' ', -1)
69
+ # Remove $
70
+ sympy = sympy.replace(r'$', ' ', -1)
71
+
72
+ # variable values
73
+ global VARIABLE_VALUES
74
+ if len(variable_values) > 0:
75
+ VARIABLE_VALUES = variable_values
76
+ else:
77
+ VARIABLE_VALUES = {}
78
+
79
+ # setup listener
80
+ matherror = MathErrorListener(sympy)
81
+
82
+ # stream input
83
+ stream = InputStream(sympy)
84
+ lex = PSLexer(stream)
85
+ lex.removeErrorListeners()
86
+ lex.addErrorListener(matherror)
87
+
88
+ tokens = CommonTokenStream(lex)
89
+ parser = PSParser(tokens)
90
+
91
+ # remove default console error listener
92
+ parser.removeErrorListeners()
93
+ parser.addErrorListener(matherror)
94
+
95
+ # process the input
96
+ return_data = None
97
+ math = parser.math()
98
+
99
+ # if a list
100
+ if math.relation_list():
101
+ return_data = []
102
+
103
+ # go over list items
104
+ relation_list = math.relation_list().relation_list_content()
105
+ for list_item in relation_list.relation():
106
+ expr = convert_relation(list_item)
107
+ return_data.append(expr)
108
+
109
+ # if not, do default
110
+ else:
111
+ relation = math.relation()
112
+ return_data = convert_relation(relation)
113
+
114
+ return return_data
115
+
116
+
117
+ class MathErrorListener(ErrorListener):
118
+ def __init__(self, src):
119
+ super(ErrorListener, self).__init__()
120
+ self.src = src
121
+
122
+ def syntaxError(self, recog, symbol, line, col, msg, e):
123
+ fmt = "%s\n%s\n%s"
124
+ marker = "~" * col + "^"
125
+
126
+ if msg.startswith("missing"):
127
+ err = fmt % (msg, self.src, marker)
128
+ elif msg.startswith("no viable"):
129
+ err = fmt % ("I expected something else here", self.src, marker)
130
+ elif msg.startswith("mismatched"):
131
+ names = PSParser.literalNames
132
+ expected = [names[i] for i in e.getExpectedTokens() if i < len(names)]
133
+ if len(expected) < 10:
134
+ expected = " ".join(expected)
135
+ err = (fmt % ("I expected one of these: " + expected,
136
+ self.src, marker))
137
+ else:
138
+ err = (fmt % ("I expected something else here", self.src, marker))
139
+ else:
140
+ err = fmt % ("I don't understand this", self.src, marker)
141
+ raise Exception(err)
142
+
143
+
144
+ def convert_relation(rel):
145
+ if rel.expr():
146
+ return convert_expr(rel.expr())
147
+
148
+ lh = convert_relation(rel.relation(0))
149
+ rh = convert_relation(rel.relation(1))
150
+ if rel.LT():
151
+ return sympy.StrictLessThan(lh, rh, evaluate=False)
152
+ elif rel.LTE():
153
+ return sympy.LessThan(lh, rh, evaluate=False)
154
+ elif rel.GT():
155
+ return sympy.StrictGreaterThan(lh, rh, evaluate=False)
156
+ elif rel.GTE():
157
+ return sympy.GreaterThan(lh, rh, evaluate=False)
158
+ elif rel.EQUAL():
159
+ return sympy.Eq(lh, rh, evaluate=False)
160
+ elif rel.ASSIGNMENT():
161
+ # !Use Global variances
162
+ if lh.is_Symbol:
163
+ # set value
164
+ variances[lh] = rh
165
+ var[str(lh)] = rh
166
+ return rh
167
+ else:
168
+ # find the symbols in lh - rh
169
+ equation = lh - rh
170
+ syms = equation.atoms(sympy.Symbol)
171
+ if len(syms) > 0:
172
+ # Solve equation
173
+ result = []
174
+ for sym in syms:
175
+ values = sympy.solve(equation, sym)
176
+ for value in values:
177
+ result.append(sympy.Eq(sym, value, evaluate=False))
178
+ return result
179
+ else:
180
+ return sympy.Eq(lh, rh, evaluate=False)
181
+ elif rel.IN():
182
+ # !Use Global variances
183
+ if hasattr(rh, 'is_Pow') and rh.is_Pow and hasattr(rh.exp, 'is_Mul'):
184
+ n = rh.exp.args[0]
185
+ m = rh.exp.args[1]
186
+ if n in variances:
187
+ n = variances[n]
188
+ if m in variances:
189
+ m = variances[m]
190
+ rh = sympy.MatrixSymbol(lh, n, m)
191
+ variances[lh] = rh
192
+ var[str(lh)] = rh
193
+ else:
194
+ raise Exception("Don't support this form of definition of matrix symbol.")
195
+ return lh
196
+ elif rel.UNEQUAL():
197
+ return sympy.Ne(lh, rh, evaluate=False)
198
+
199
+
200
+ def convert_expr(expr):
201
+ if expr.additive():
202
+ return convert_add(expr.additive())
203
+
204
+
205
+ def convert_elementary_transform(matrix, transform):
206
+ if transform.transform_scale():
207
+ transform_scale = transform.transform_scale()
208
+ transform_atom = transform_scale.transform_atom()
209
+ k = None
210
+ num = int(transform_atom.NUMBER().getText()) - 1
211
+ if transform_scale.expr():
212
+ k = convert_expr(transform_scale.expr())
213
+ elif transform_scale.group():
214
+ k = convert_expr(transform_scale.group().expr())
215
+ elif transform_scale.SUB():
216
+ k = -1
217
+ else:
218
+ k = 1
219
+ if transform_atom.LETTER_NO_E().getText() == 'r':
220
+ matrix = matrix.elementary_row_op(op='n->kn', row=num, k=k)
221
+ elif transform_atom.LETTER_NO_E().getText() == 'c':
222
+ matrix = matrix.elementary_col_op(op='n->kn', col=num, k=k)
223
+ else:
224
+ raise Exception('Row and col don\'s match')
225
+
226
+ elif transform.transform_swap():
227
+ first_atom = transform.transform_swap().transform_atom()[0]
228
+ second_atom = transform.transform_swap().transform_atom()[1]
229
+ first_num = int(first_atom.NUMBER().getText()) - 1
230
+ second_num = int(second_atom.NUMBER().getText()) - 1
231
+ if first_atom.LETTER_NO_E().getText() != second_atom.LETTER_NO_E().getText():
232
+ raise Exception('Row and col don\'s match')
233
+ elif first_atom.LETTER_NO_E().getText() == 'r':
234
+ matrix = matrix.elementary_row_op(op='n<->m', row1=first_num, row2=second_num)
235
+ elif first_atom.LETTER_NO_E().getText() == 'c':
236
+ matrix = matrix.elementary_col_op(op='n<->m', col1=first_num, col2=second_num)
237
+ else:
238
+ raise Exception('Row and col don\'s match')
239
+
240
+ elif transform.transform_assignment():
241
+ first_atom = transform.transform_assignment().transform_atom()
242
+ second_atom = transform.transform_assignment().transform_scale().transform_atom()
243
+ transform_scale = transform.transform_assignment().transform_scale()
244
+ k = None
245
+ if transform_scale.expr():
246
+ k = convert_expr(transform_scale.expr())
247
+ elif transform_scale.group():
248
+ k = convert_expr(transform_scale.group().expr())
249
+ elif transform_scale.SUB():
250
+ k = -1
251
+ else:
252
+ k = 1
253
+ first_num = int(first_atom.NUMBER().getText()) - 1
254
+ second_num = int(second_atom.NUMBER().getText()) - 1
255
+ if first_atom.LETTER_NO_E().getText() != second_atom.LETTER_NO_E().getText():
256
+ raise Exception('Row and col don\'s match')
257
+ elif first_atom.LETTER_NO_E().getText() == 'r':
258
+ matrix = matrix.elementary_row_op(op='n->n+km', k=k, row1=first_num, row2=second_num)
259
+ elif first_atom.LETTER_NO_E().getText() == 'c':
260
+ matrix = matrix.elementary_col_op(op='n->n+km', k=k, col1=first_num, col2=second_num)
261
+ else:
262
+ raise Exception('Row and col don\'s match')
263
+
264
+ return matrix
265
+
266
+
267
+ def convert_matrix(matrix):
268
+ # build matrix
269
+ row = matrix.matrix_row()
270
+ tmp = []
271
+ rows = 0
272
+ mat = None
273
+
274
+ for r in row:
275
+ tmp.append([])
276
+ for expr in r.expr():
277
+ tmp[rows].append(convert_expr(expr))
278
+ rows = rows + 1
279
+
280
+ mat = sympy.Matrix(tmp)
281
+
282
+ if hasattr(matrix, 'MATRIX_XRIGHTARROW') and matrix.MATRIX_XRIGHTARROW():
283
+ transforms_list = matrix.elementary_transforms()
284
+ if len(transforms_list) == 1:
285
+ for transform in transforms_list[0].elementary_transform():
286
+ mat = convert_elementary_transform(mat, transform)
287
+ elif len(transforms_list) == 2:
288
+ # firstly transform top of xrightarrow
289
+ for transform in transforms_list[1].elementary_transform():
290
+ mat = convert_elementary_transform(mat, transform)
291
+ # firstly transform bottom of xrightarrow
292
+ for transform in transforms_list[0].elementary_transform():
293
+ mat = convert_elementary_transform(mat, transform)
294
+
295
+ return mat
296
+
297
+
298
+ def add_flat(lh, rh):
299
+ if hasattr(lh, 'is_Add') and lh.is_Add or hasattr(rh, 'is_Add') and rh.is_Add:
300
+ args = []
301
+ if hasattr(lh, 'is_Add') and lh.is_Add:
302
+ args += list(lh.args)
303
+ else:
304
+ args += [lh]
305
+ if hasattr(rh, 'is_Add') and rh.is_Add:
306
+ args = args + list(rh.args)
307
+ else:
308
+ args += [rh]
309
+ return sympy.Add(*args, evaluate=False)
310
+ else:
311
+ return sympy.Add(lh, rh, evaluate=False)
312
+
313
+
314
+ def mat_add_flat(lh, rh):
315
+ if hasattr(lh, 'is_MatAdd') and lh.is_MatAdd or hasattr(rh, 'is_MatAdd') and rh.is_MatAdd:
316
+ args = []
317
+ if hasattr(lh, 'is_MatAdd') and lh.is_MatAdd:
318
+ args += list(lh.args)
319
+ else:
320
+ args += [lh]
321
+ if hasattr(rh, 'is_MatAdd') and rh.is_MatAdd:
322
+ args = args + list(rh.args)
323
+ else:
324
+ args += [rh]
325
+ return sympy.MatAdd(*[arg.doit() for arg in args], evaluate=False)
326
+ else:
327
+ return sympy.MatAdd(lh.doit(), rh.doit(), evaluate=False)
328
+
329
+
330
+ def mul_flat(lh, rh):
331
+ if hasattr(lh, 'is_Mul') and lh.is_Mul or hasattr(rh, 'is_Mul') and rh.is_Mul:
332
+ args = []
333
+ if hasattr(lh, 'is_Mul') and lh.is_Mul:
334
+ args += list(lh.args)
335
+ else:
336
+ args += [lh]
337
+ if hasattr(rh, 'is_Mul') and rh.is_Mul:
338
+ args = args + list(rh.args)
339
+ else:
340
+ args += [rh]
341
+ return sympy.Mul(*args, evaluate=False)
342
+ else:
343
+ return sympy.Mul(lh, rh, evaluate=False)
344
+
345
+
346
+ def mat_mul_flat(lh, rh):
347
+ if hasattr(lh, 'is_MatMul') and lh.is_MatMul or hasattr(rh, 'is_MatMul') and rh.is_MatMul:
348
+ args = []
349
+ if hasattr(lh, 'is_MatMul') and lh.is_MatMul:
350
+ args += list(lh.args)
351
+ else:
352
+ args += [lh]
353
+ if hasattr(rh, 'is_MatMul') and rh.is_MatMul:
354
+ args = args + list(rh.args)
355
+ else:
356
+ args += [rh]
357
+ return sympy.MatMul(*[arg.doit() for arg in args], evaluate=False)
358
+ else:
359
+ if hasattr(lh, 'doit') and hasattr(rh, 'doit'):
360
+ return sympy.MatMul(lh.doit(), rh.doit(), evaluate=False)
361
+ elif hasattr(lh, 'doit') and not hasattr(rh, 'doit'):
362
+ return sympy.MatMul(lh.doit(), rh, evaluate=False)
363
+ elif not hasattr(lh, 'doit') and hasattr(rh, 'doit'):
364
+ return sympy.MatMul(lh, rh.doit(), evaluate=False)
365
+ else:
366
+ return sympy.MatMul(lh, rh, evaluate=False)
367
+
368
+
369
+ def convert_add(add):
370
+ if add.ADD():
371
+ lh = convert_add(add.additive(0))
372
+ rh = convert_add(add.additive(1))
373
+
374
+ if lh.is_Matrix or rh.is_Matrix:
375
+ return mat_add_flat(lh, rh)
376
+ else:
377
+ return add_flat(lh, rh)
378
+ elif add.SUB():
379
+ lh = convert_add(add.additive(0))
380
+ rh = convert_add(add.additive(1))
381
+
382
+ if lh.is_Matrix or rh.is_Matrix:
383
+ return mat_add_flat(lh, mat_mul_flat(-1, rh))
384
+ else:
385
+ # If we want to force ordering for variables this should be:
386
+ # return Sub(lh, rh, evaluate=False)
387
+ if not rh.is_Matrix and rh.func.is_Number:
388
+ rh = -rh
389
+ else:
390
+ rh = mul_flat(-1, rh)
391
+ return add_flat(lh, rh)
392
+ else:
393
+ return convert_mp(add.mp())
394
+
395
+
396
+ def convert_mp(mp):
397
+ if hasattr(mp, 'mp'):
398
+ mp_left = mp.mp(0)
399
+ mp_right = mp.mp(1)
400
+ else:
401
+ mp_left = mp.mp_nofunc(0)
402
+ mp_right = mp.mp_nofunc(1)
403
+
404
+ if mp.MUL() or mp.CMD_TIMES() or mp.CMD_CDOT():
405
+ lh = convert_mp(mp_left)
406
+ rh = convert_mp(mp_right)
407
+
408
+ if lh.is_Matrix or rh.is_Matrix:
409
+ return mat_mul_flat(lh, rh)
410
+ else:
411
+ return mul_flat(lh, rh)
412
+ elif mp.DIV() or mp.CMD_DIV() or mp.COLON():
413
+ lh = convert_mp(mp_left)
414
+ rh = convert_mp(mp_right)
415
+ if lh.is_Matrix or rh.is_Matrix:
416
+ return sympy.MatMul(lh, sympy.Pow(rh, -1, evaluate=False), evaluate=False)
417
+ else:
418
+ return sympy.Mul(lh, sympy.Pow(rh, -1, evaluate=False), evaluate=False)
419
+ elif mp.CMD_MOD():
420
+ lh = convert_mp(mp_left)
421
+ rh = convert_mp(mp_right)
422
+ if rh.is_Matrix:
423
+ raise Exception("Cannot perform modulo operation with a matrix as an operand")
424
+ else:
425
+ return sympy.Mod(lh, rh, evaluate=False)
426
+ else:
427
+ if hasattr(mp, 'unary'):
428
+ return convert_unary(mp.unary())
429
+ else:
430
+ return convert_unary(mp.unary_nofunc())
431
+
432
+
433
+ def convert_unary(unary):
434
+ if hasattr(unary, 'unary'):
435
+ nested_unary = unary.unary()
436
+ else:
437
+ nested_unary = unary.unary_nofunc()
438
+ if hasattr(unary, 'postfix_nofunc'):
439
+ first = unary.postfix()
440
+ tail = unary.postfix_nofunc()
441
+ postfix = [first] + tail
442
+ else:
443
+ postfix = unary.postfix()
444
+
445
+ if unary.ADD():
446
+ return convert_unary(nested_unary)
447
+ elif unary.SUB():
448
+ tmp_convert_nested_unary = convert_unary(nested_unary)
449
+ if tmp_convert_nested_unary.is_Matrix:
450
+ return mat_mul_flat(-1, tmp_convert_nested_unary, evaluate=False)
451
+ else:
452
+ if tmp_convert_nested_unary.func.is_Number:
453
+ return -tmp_convert_nested_unary
454
+ else:
455
+ return mul_flat(-1, tmp_convert_nested_unary)
456
+ elif postfix:
457
+ return convert_postfix_list(postfix)
458
+
459
+
460
+ def convert_postfix_list(arr, i=0):
461
+ if i >= len(arr):
462
+ raise Exception("Index out of bounds")
463
+
464
+ res = convert_postfix(arr[i])
465
+
466
+ if isinstance(res, sympy.Expr) or isinstance(res, sympy.Matrix) or res is sympy.S.EmptySet:
467
+ if i == len(arr) - 1:
468
+ return res # nothing to multiply by
469
+ else:
470
+ # multiply by next
471
+ rh = convert_postfix_list(arr, i + 1)
472
+
473
+ if res.is_Matrix or rh.is_Matrix:
474
+ return mat_mul_flat(res, rh)
475
+ else:
476
+ return mul_flat(res, rh)
477
+ elif isinstance(res, tuple) or isinstance(res, list) or isinstance(res, dict):
478
+ return res
479
+ else: # must be derivative
480
+ wrt = res[0]
481
+ if i == len(arr) - 1:
482
+ raise Exception("Expected expression for derivative")
483
+ else:
484
+ expr = convert_postfix_list(arr, i + 1)
485
+ return sympy.Derivative(expr, wrt)
486
+
487
+
488
+ def do_subs(expr, at):
489
+ if at.expr():
490
+ at_expr = convert_expr(at.expr())
491
+ syms = at_expr.atoms(sympy.Symbol)
492
+ if len(syms) == 0:
493
+ return expr
494
+ elif len(syms) > 0:
495
+ sym = next(iter(syms))
496
+ return expr.subs(sym, at_expr)
497
+ elif at.equality():
498
+ lh = convert_expr(at.equality().expr(0))
499
+ rh = convert_expr(at.equality().expr(1))
500
+ return expr.subs(lh, rh)
501
+
502
+
503
+ def convert_postfix(postfix):
504
+ if hasattr(postfix, 'exp'):
505
+ exp_nested = postfix.exp()
506
+ else:
507
+ exp_nested = postfix.exp_nofunc()
508
+
509
+ exp = convert_exp(exp_nested)
510
+ for op in postfix.postfix_op():
511
+ if op.BANG():
512
+ if isinstance(exp, list):
513
+ raise Exception("Cannot apply postfix to derivative")
514
+ exp = sympy.factorial(exp, evaluate=False)
515
+ elif op.eval_at():
516
+ ev = op.eval_at()
517
+ at_b = None
518
+ at_a = None
519
+ if ev.eval_at_sup():
520
+ at_b = do_subs(exp, ev.eval_at_sup())
521
+ if ev.eval_at_sub():
522
+ at_a = do_subs(exp, ev.eval_at_sub())
523
+ if at_b is not None and at_a is not None:
524
+ exp = add_flat(at_b, mul_flat(at_a, -1))
525
+ elif at_b is not None:
526
+ exp = at_b
527
+ elif at_a is not None:
528
+ exp = at_a
529
+ elif op.transpose():
530
+ try:
531
+ exp = exp.T
532
+ except:
533
+ try:
534
+ exp = sympy.transpose(exp)
535
+ except:
536
+ pass
537
+ pass
538
+
539
+ return exp
540
+
541
+
542
+ def convert_exp(exp):
543
+ if hasattr(exp, 'exp'):
544
+ exp_nested = exp.exp()
545
+ else:
546
+ exp_nested = exp.exp_nofunc()
547
+
548
+ if exp_nested:
549
+ base = convert_exp(exp_nested)
550
+ if isinstance(base, list):
551
+ raise Exception("Cannot raise derivative to power")
552
+ if exp.atom():
553
+ exponent = convert_atom(exp.atom())
554
+ elif exp.expr():
555
+ exponent = convert_expr(exp.expr())
556
+ return sympy.Pow(base, exponent, evaluate=False)
557
+ else:
558
+ if hasattr(exp, 'comp'):
559
+ return convert_comp(exp.comp())
560
+ else:
561
+ return convert_comp(exp.comp_nofunc())
562
+
563
+
564
+ def convert_comp(comp):
565
+ if comp.group():
566
+ return convert_expr(comp.group().expr())
567
+ elif comp.norm_group():
568
+ return convert_expr(comp.norm_group().expr()).norm()
569
+ elif comp.abs_group():
570
+ return sympy.Abs(convert_expr(comp.abs_group().expr()), evaluate=False)
571
+ elif comp.floor_group():
572
+ return handle_floor(convert_expr(comp.floor_group().expr()))
573
+ elif comp.ceil_group():
574
+ return handle_ceil(convert_expr(comp.ceil_group().expr()))
575
+ elif comp.atom():
576
+ return convert_atom(comp.atom())
577
+ elif comp.frac():
578
+ return convert_frac(comp.frac())
579
+ elif comp.binom():
580
+ return convert_binom(comp.binom())
581
+ elif comp.matrix():
582
+ return convert_matrix(comp.matrix())
583
+ elif comp.det():
584
+ # !Use Global variances
585
+ return convert_matrix(comp.det()).subs(variances).det()
586
+ elif comp.func():
587
+ return convert_func(comp.func())
588
+
589
+
590
+ def convert_atom(atom):
591
+ if atom.atom_expr():
592
+ atom_expr = atom.atom_expr()
593
+
594
+ # find the atom's text
595
+ atom_text = ''
596
+ if atom_expr.LETTER_NO_E():
597
+ atom_text = atom_expr.LETTER_NO_E().getText()
598
+ if atom_text == "I":
599
+ return sympy.I
600
+ elif atom_expr.GREEK_CMD():
601
+ atom_text = atom_expr.GREEK_CMD().getText()[1:].strip()
602
+ elif atom_expr.OTHER_SYMBOL_CMD():
603
+ atom_text = atom_expr.OTHER_SYMBOL_CMD().getText().strip()
604
+ elif atom_expr.accent():
605
+ atom_accent = atom_expr.accent()
606
+ # get name for accent
607
+ name = atom_accent.start.text
608
+ # name = atom_accent.start.text[1:]
609
+ # exception: check if bar or overline which are treated both as bar
610
+ # if name in ["bar", "overline"]:
611
+ # name = "bar"
612
+ # if name in ["vec", "overrightarrow"]:
613
+ # name = "vec"
614
+ # if name in ["tilde", "widetilde"]:
615
+ # name = "tilde"
616
+ # get the base (variable)
617
+ base = atom_accent.base.getText()
618
+ # set string to base+name
619
+ atom_text = name + '{' + base + '}'
620
+
621
+ # find atom's subscript, if any
622
+ subscript_text = ''
623
+ if atom_expr.subexpr():
624
+ subexpr = atom_expr.subexpr()
625
+ subscript = None
626
+ if subexpr.expr(): # subscript is expr
627
+ subscript = subexpr.expr().getText().strip()
628
+ elif subexpr.atom(): # subscript is atom
629
+ subscript = subexpr.atom().getText().strip()
630
+ elif subexpr.args(): # subscript is args
631
+ subscript = subexpr.args().getText().strip()
632
+ subscript_inner_text = StrPrinter().doprint(subscript)
633
+ if len(subscript_inner_text) > 1:
634
+ subscript_text = '_{' + subscript_inner_text + '}'
635
+ else:
636
+ subscript_text = '_' + subscript_inner_text
637
+
638
+ # construct the symbol using the text and optional subscript
639
+ atom_symbol = sympy.Symbol(atom_text + subscript_text, real=is_real)
640
+ # for matrix symbol
641
+ matrix_symbol = None
642
+ global var
643
+ if atom_text + subscript_text in var:
644
+ try:
645
+ rh = var[atom_text + subscript_text]
646
+ shape = sympy.shape(rh)
647
+ matrix_symbol = sympy.MatrixSymbol(atom_text + subscript_text, shape[0], shape[1])
648
+ variances[matrix_symbol] = variances[atom_symbol]
649
+ except:
650
+ pass
651
+
652
+ # find the atom's superscript, and return as a Pow if found
653
+ if atom_expr.supexpr():
654
+ supexpr = atom_expr.supexpr()
655
+ func_pow = None
656
+ if supexpr.expr():
657
+ func_pow = convert_expr(supexpr.expr())
658
+ else:
659
+ func_pow = convert_atom(supexpr.atom())
660
+ return sympy.Pow(atom_symbol, func_pow, evaluate=False)
661
+
662
+ return atom_symbol if not matrix_symbol else matrix_symbol
663
+ elif atom.SYMBOL():
664
+ s = atom.SYMBOL().getText().replace("\\$", "").replace("\\%", "")
665
+ if s == "\\infty":
666
+ return sympy.oo
667
+ elif s == '\\pi':
668
+ return sympy.pi
669
+ elif s == '\\emptyset':
670
+ return sympy.S.EmptySet
671
+ else:
672
+ raise Exception("Unrecognized symbol")
673
+ elif atom.NUMBER():
674
+ s = atom.NUMBER().getText().replace(",", "")
675
+ try:
676
+ sr = sympy.Rational(s)
677
+ return sr
678
+ except (TypeError, ValueError):
679
+ return sympy.Number(s)
680
+ elif atom.E_NOTATION():
681
+ s = atom.E_NOTATION().getText().replace(",", "")
682
+ try:
683
+ sr = sympy.Rational(s)
684
+ return sr
685
+ except (TypeError, ValueError):
686
+ return sympy.Number(s)
687
+ elif atom.DIFFERENTIAL():
688
+ var = get_differential_var(atom.DIFFERENTIAL())
689
+ return sympy.Symbol('d' + var.name, real=is_real)
690
+ elif atom.mathit():
691
+ text = rule2text(atom.mathit().mathit_text())
692
+ return sympy.Symbol(text, real=is_real)
693
+ elif atom.VARIABLE():
694
+ text = atom.VARIABLE().getText()
695
+ is_percent = text.endswith("\\%")
696
+ trim_amount = 3 if is_percent else 1
697
+ name = text[10:]
698
+ name = name[0:len(name) - trim_amount]
699
+
700
+ # add hash to distinguish from regular symbols
701
+ hash = hashlib.md5(name.encode()).hexdigest()
702
+ symbol_name = name + hash
703
+
704
+ # replace the variable for already known variable values
705
+ if name in VARIABLE_VALUES:
706
+ # if a sympy class
707
+ if isinstance(VARIABLE_VALUES[name], tuple(sympy.core.all_classes)):
708
+ symbol = VARIABLE_VALUES[name]
709
+
710
+ # if NOT a sympy class
711
+ else:
712
+ symbol = parse_expr(str(VARIABLE_VALUES[name]))
713
+ else:
714
+ symbol = sympy.Symbol(symbol_name, real=is_real)
715
+
716
+ if is_percent:
717
+ return sympy.Mul(symbol, sympy.Pow(100, -1, evaluate=False), evaluate=False)
718
+
719
+ # return the symbol
720
+ return symbol
721
+
722
+ elif atom.PERCENT_NUMBER():
723
+ text = atom.PERCENT_NUMBER().getText().replace("\\%", "").replace(",", "")
724
+ try:
725
+ number = sympy.Rational(text)
726
+ except (TypeError, ValueError):
727
+ number = sympy.Number(text)
728
+ percent = sympy.Rational(number, 100)
729
+ return percent
730
+
731
+
732
+ def rule2text(ctx):
733
+ stream = ctx.start.getInputStream()
734
+ # starting index of starting token
735
+ startIdx = ctx.start.start
736
+ # stopping index of stopping token
737
+ stopIdx = ctx.stop.stop
738
+
739
+ return stream.getText(startIdx, stopIdx)
740
+
741
+
742
+ def convert_frac(frac):
743
+ diff_op = False
744
+ partial_op = False
745
+ lower_itv = frac.lower.getSourceInterval()
746
+ lower_itv_len = lower_itv[1] - lower_itv[0] + 1
747
+ if (frac.lower.start == frac.lower.stop and
748
+ frac.lower.start.type == PSLexer.DIFFERENTIAL):
749
+ wrt = get_differential_var_str(frac.lower.start.text)
750
+ diff_op = True
751
+ elif (lower_itv_len == 2 and
752
+ frac.lower.start.type == PSLexer.SYMBOL and
753
+ frac.lower.start.text == '\\partial' and
754
+ (frac.lower.stop.type == PSLexer.LETTER_NO_E or frac.lower.stop.type == PSLexer.SYMBOL)):
755
+ partial_op = True
756
+ wrt = frac.lower.stop.text
757
+ if frac.lower.stop.type == PSLexer.SYMBOL:
758
+ wrt = wrt[1:]
759
+
760
+ if diff_op or partial_op:
761
+ wrt = sympy.Symbol(wrt, real=is_real)
762
+ if (diff_op and frac.upper.start == frac.upper.stop and
763
+ frac.upper.start.type == PSLexer.LETTER_NO_E and
764
+ frac.upper.start.text == 'd'):
765
+ return [wrt]
766
+ elif (partial_op and frac.upper.start == frac.upper.stop and
767
+ frac.upper.start.type == PSLexer.SYMBOL and
768
+ frac.upper.start.text == '\\partial'):
769
+ return [wrt]
770
+ upper_text = rule2text(frac.upper)
771
+
772
+ expr_top = None
773
+ if diff_op and upper_text.startswith('d'):
774
+ expr_top = latex2sympy(upper_text[1:])
775
+ elif partial_op and frac.upper.start.text == '\\partial':
776
+ expr_top = latex2sympy(upper_text[len('\\partial'):])
777
+ if expr_top:
778
+ return sympy.Derivative(expr_top, wrt)
779
+
780
+ expr_top = convert_expr(frac.upper)
781
+ expr_bot = convert_expr(frac.lower)
782
+ if expr_top.is_Matrix or expr_bot.is_Matrix:
783
+ return sympy.MatMul(expr_top, sympy.Pow(expr_bot, -1, evaluate=False), evaluate=False)
784
+ else:
785
+ return sympy.Mul(expr_top, sympy.Pow(expr_bot, -1, evaluate=False), evaluate=False)
786
+
787
+
788
+ def convert_binom(binom):
789
+ expr_top = convert_expr(binom.upper)
790
+ expr_bot = convert_expr(binom.lower)
791
+ return sympy.binomial(expr_top, expr_bot)
792
+
793
+
794
+ def convert_func(func):
795
+ if func.func_normal_single_arg():
796
+ if func.L_PAREN(): # function called with parenthesis
797
+ arg = convert_func_arg(func.func_single_arg())
798
+ else:
799
+ arg = convert_func_arg(func.func_single_arg_noparens())
800
+
801
+ name = func.func_normal_single_arg().start.text[1:]
802
+
803
+ # change arc<trig> -> a<trig>
804
+ if name in ["arcsin", "arccos", "arctan", "arccsc", "arcsec",
805
+ "arccot"]:
806
+ name = "a" + name[3:]
807
+ expr = getattr(sympy.functions, name)(arg, evaluate=False)
808
+ elif name in ["arsinh", "arcosh", "artanh"]:
809
+ name = "a" + name[2:]
810
+ expr = getattr(sympy.functions, name)(arg, evaluate=False)
811
+ elif name in ["arcsinh", "arccosh", "arctanh"]:
812
+ name = "a" + name[3:]
813
+ expr = getattr(sympy.functions, name)(arg, evaluate=False)
814
+ elif name == "operatorname":
815
+ operatorname = func.func_normal_single_arg().func_operator_name.getText()
816
+
817
+ if operatorname in ["arsinh", "arcosh", "artanh"]:
818
+ operatorname = "a" + operatorname[2:]
819
+ expr = getattr(sympy.functions, operatorname)(arg, evaluate=False)
820
+ elif operatorname in ["arcsinh", "arccosh", "arctanh"]:
821
+ operatorname = "a" + operatorname[3:]
822
+ expr = getattr(sympy.functions, operatorname)(arg, evaluate=False)
823
+ elif operatorname == "floor":
824
+ expr = handle_floor(arg)
825
+ elif operatorname == "ceil":
826
+ expr = handle_ceil(arg)
827
+ elif operatorname == 'eye':
828
+ expr = sympy.eye(arg)
829
+ elif operatorname == 'rank':
830
+ expr = sympy.Integer(arg.rank())
831
+ elif operatorname in ['trace', 'tr']:
832
+ expr = arg.trace()
833
+ elif operatorname == 'rref':
834
+ expr = arg.rref()[0]
835
+ elif operatorname == 'nullspace':
836
+ expr = arg.nullspace()
837
+ elif operatorname == 'norm':
838
+ expr = arg.norm()
839
+ elif operatorname == 'cols':
840
+ expr = [arg.col(i) for i in range(arg.cols)]
841
+ elif operatorname == 'rows':
842
+ expr = [arg.row(i) for i in range(arg.rows)]
843
+ elif operatorname in ['eig', 'eigen', 'diagonalize']:
844
+ expr = arg.diagonalize()
845
+ elif operatorname in ['eigenvals', 'eigenvalues']:
846
+ expr = arg.eigenvals()
847
+ elif operatorname in ['eigenvects', 'eigenvectors']:
848
+ expr = arg.eigenvects()
849
+ elif operatorname in ['svd', 'SVD']:
850
+ expr = arg.singular_value_decomposition()
851
+ elif name in ["log", "ln"]:
852
+ if func.subexpr():
853
+ if func.subexpr().atom():
854
+ base = convert_atom(func.subexpr().atom())
855
+ else:
856
+ base = convert_expr(func.subexpr().expr())
857
+ elif name == "log":
858
+ base = 10
859
+ elif name == "ln":
860
+ base = sympy.E
861
+ expr = sympy.log(arg, base, evaluate=False)
862
+ elif name in ["exp", "exponentialE"]:
863
+ expr = sympy.exp(arg)
864
+ elif name == "floor":
865
+ expr = handle_floor(arg)
866
+ elif name == "ceil":
867
+ expr = handle_ceil(arg)
868
+ elif name == 'det':
869
+ expr = arg.det()
870
+
871
+ func_pow = None
872
+ should_pow = True
873
+ if func.supexpr():
874
+ if func.supexpr().expr():
875
+ func_pow = convert_expr(func.supexpr().expr())
876
+ else:
877
+ func_pow = convert_atom(func.supexpr().atom())
878
+
879
+ if name in ["sin", "cos", "tan", "csc", "sec", "cot", "sinh", "cosh", "tanh"]:
880
+ if func_pow == -1:
881
+ name = "a" + name
882
+ should_pow = False
883
+ expr = getattr(sympy.functions, name)(arg, evaluate=False)
884
+
885
+ if func_pow and should_pow:
886
+ expr = sympy.Pow(expr, func_pow, evaluate=False)
887
+
888
+ return expr
889
+
890
+ elif func.func_normal_multi_arg():
891
+ if func.L_PAREN(): # function called with parenthesis
892
+ args = func.func_multi_arg().getText().split(",")
893
+ else:
894
+ args = func.func_multi_arg_noparens().split(",")
895
+
896
+ args = list(map(lambda arg: latex2sympy(arg, VARIABLE_VALUES), args))
897
+ name = func.func_normal_multi_arg().start.text[1:]
898
+
899
+ if name == "operatorname":
900
+ operatorname = func.func_normal_multi_arg().func_operator_name.getText()
901
+ if operatorname in ["gcd", "lcm"]:
902
+ expr = handle_gcd_lcm(operatorname, args)
903
+ elif operatorname == 'zeros':
904
+ expr = sympy.zeros(*args)
905
+ elif operatorname == 'ones':
906
+ expr = sympy.ones(*args)
907
+ elif operatorname == 'diag':
908
+ expr = sympy.diag(*args)
909
+ elif operatorname == 'hstack':
910
+ expr = sympy.Matrix.hstack(*args)
911
+ elif operatorname == 'vstack':
912
+ expr = sympy.Matrix.vstack(*args)
913
+ elif operatorname in ['orth', 'ortho', 'orthogonal', 'orthogonalize']:
914
+ if len(args) == 1:
915
+ arg = args[0]
916
+ expr = sympy.matrices.GramSchmidt([arg.col(i) for i in range(arg.cols)], True)
917
+ else:
918
+ expr = sympy.matrices.GramSchmidt(args, True)
919
+ elif name in ["gcd", "lcm"]:
920
+ expr = handle_gcd_lcm(name, args)
921
+ elif name in ["max", "min"]:
922
+ name = name[0].upper() + name[1:]
923
+ expr = getattr(sympy.functions, name)(*args, evaluate=False)
924
+
925
+ func_pow = None
926
+ should_pow = True
927
+ if func.supexpr():
928
+ if func.supexpr().expr():
929
+ func_pow = convert_expr(func.supexpr().expr())
930
+ else:
931
+ func_pow = convert_atom(func.supexpr().atom())
932
+
933
+ if func_pow and should_pow:
934
+ expr = sympy.Pow(expr, func_pow, evaluate=False)
935
+
936
+ return expr
937
+ elif func.atom_expr_no_supexpr():
938
+ # define a function
939
+ f = sympy.Function(func.atom_expr_no_supexpr().getText())
940
+ # args
941
+ args = func.func_common_args().getText().split(",")
942
+ if args[-1] == '':
943
+ args = args[:-1]
944
+ args = [latex2sympy(arg, VARIABLE_VALUES) for arg in args]
945
+ # supexpr
946
+ if func.supexpr():
947
+ if func.supexpr().expr():
948
+ expr = convert_expr(func.supexpr().expr())
949
+ else:
950
+ expr = convert_atom(func.supexpr().atom())
951
+ return sympy.Pow(f(*args), expr, evaluate=False)
952
+ else:
953
+ return f(*args)
954
+ elif func.FUNC_INT():
955
+ return handle_integral(func)
956
+ elif func.FUNC_SQRT():
957
+ expr = convert_expr(func.base)
958
+ if func.root:
959
+ r = convert_expr(func.root)
960
+ return sympy.Pow(expr, 1 / r, evaluate=False)
961
+ else:
962
+ return sympy.Pow(expr, sympy.S.Half, evaluate=False)
963
+ elif func.FUNC_SUM():
964
+ return handle_sum_or_prod(func, "summation")
965
+ elif func.FUNC_PROD():
966
+ return handle_sum_or_prod(func, "product")
967
+ elif func.FUNC_LIM():
968
+ return handle_limit(func)
969
+ elif func.EXP_E():
970
+ return handle_exp(func)
971
+
972
+
973
+ def convert_func_arg(arg):
974
+ if hasattr(arg, 'expr'):
975
+ return convert_expr(arg.expr())
976
+ else:
977
+ return convert_mp(arg.mp_nofunc())
978
+
979
+
980
+ def handle_integral(func):
981
+ if func.additive():
982
+ integrand = convert_add(func.additive())
983
+ elif func.frac():
984
+ integrand = convert_frac(func.frac())
985
+ else:
986
+ integrand = 1
987
+
988
+ int_var = None
989
+ if func.DIFFERENTIAL():
990
+ int_var = get_differential_var(func.DIFFERENTIAL())
991
+ else:
992
+ for sym in integrand.atoms(sympy.Symbol):
993
+ s = str(sym)
994
+ if len(s) > 1 and s[0] == 'd':
995
+ if s[1] == '\\':
996
+ int_var = sympy.Symbol(s[2:], real=is_real)
997
+ else:
998
+ int_var = sympy.Symbol(s[1:], real=is_real)
999
+ int_sym = sym
1000
+ if int_var:
1001
+ integrand = integrand.subs(int_sym, 1)
1002
+ else:
1003
+ # Assume dx by default
1004
+ int_var = sympy.Symbol('x', real=is_real)
1005
+
1006
+ if func.subexpr():
1007
+ if func.subexpr().atom():
1008
+ lower = convert_atom(func.subexpr().atom())
1009
+ else:
1010
+ lower = convert_expr(func.subexpr().expr())
1011
+ if func.supexpr().atom():
1012
+ upper = convert_atom(func.supexpr().atom())
1013
+ else:
1014
+ upper = convert_expr(func.supexpr().expr())
1015
+ return sympy.Integral(integrand, (int_var, lower, upper))
1016
+ else:
1017
+ return sympy.Integral(integrand, int_var)
1018
+
1019
+
1020
+ def handle_sum_or_prod(func, name):
1021
+ val = convert_mp(func.mp())
1022
+ iter_var = convert_expr(func.subeq().equality().expr(0))
1023
+ start = convert_expr(func.subeq().equality().expr(1))
1024
+ if func.supexpr().expr(): # ^{expr}
1025
+ end = convert_expr(func.supexpr().expr())
1026
+ else: # ^atom
1027
+ end = convert_atom(func.supexpr().atom())
1028
+
1029
+ if name == "summation":
1030
+ return sympy.Sum(val, (iter_var, start, end))
1031
+ elif name == "product":
1032
+ return sympy.Product(val, (iter_var, start, end))
1033
+
1034
+
1035
+ def handle_limit(func):
1036
+ sub = func.limit_sub()
1037
+ if sub.LETTER_NO_E():
1038
+ var = sympy.Symbol(sub.LETTER_NO_E().getText(), real=is_real)
1039
+ elif sub.GREEK_CMD():
1040
+ var = sympy.Symbol(sub.GREEK_CMD().getText()[1:].strip(), real=is_real)
1041
+ elif sub.OTHER_SYMBOL_CMD():
1042
+ var = sympy.Symbol(sub.OTHER_SYMBOL_CMD().getText().strip(), real=is_real)
1043
+ else:
1044
+ var = sympy.Symbol('x', real=is_real)
1045
+ if sub.SUB():
1046
+ direction = "-"
1047
+ else:
1048
+ direction = "+"
1049
+ approaching = convert_expr(sub.expr())
1050
+ content = convert_mp(func.mp())
1051
+
1052
+ return sympy.Limit(content, var, approaching, direction)
1053
+
1054
+
1055
+ def handle_exp(func):
1056
+ if func.supexpr():
1057
+ if func.supexpr().expr(): # ^{expr}
1058
+ exp_arg = convert_expr(func.supexpr().expr())
1059
+ else: # ^atom
1060
+ exp_arg = convert_atom(func.supexpr().atom())
1061
+ else:
1062
+ exp_arg = 1
1063
+ return sympy.exp(exp_arg)
1064
+
1065
+
1066
+ def handle_gcd_lcm(f, args):
1067
+ """
1068
+ Return the result of gcd() or lcm(), as UnevaluatedExpr
1069
+
1070
+ f: str - name of function ("gcd" or "lcm")
1071
+ args: List[Expr] - list of function arguments
1072
+ """
1073
+
1074
+ args = tuple(map(sympy.nsimplify, args))
1075
+
1076
+ # gcd() and lcm() don't support evaluate=False
1077
+ return sympy.UnevaluatedExpr(getattr(sympy, f)(args))
1078
+
1079
+
1080
+ def handle_floor(expr):
1081
+ """
1082
+ Apply floor() then return the floored expression.
1083
+
1084
+ expr: Expr - sympy expression as an argument to floor()
1085
+ """
1086
+ return sympy.functions.floor(expr, evaluate=False)
1087
+
1088
+
1089
+ def handle_ceil(expr):
1090
+ """
1091
+ Apply ceil() then return the ceil-ed expression.
1092
+
1093
+ expr: Expr - sympy expression as an argument to ceil()
1094
+ """
1095
+ return sympy.functions.ceiling(expr, evaluate=False)
1096
+
1097
+
1098
+ def get_differential_var(d):
1099
+ text = get_differential_var_str(d.getText())
1100
+ return sympy.Symbol(text, real=is_real)
1101
+
1102
+
1103
+ def get_differential_var_str(text):
1104
+ for i in range(1, len(text)):
1105
+ c = text[i]
1106
+ if not (c == " " or c == "\r" or c == "\n" or c == "\t"):
1107
+ idx = i
1108
+ break
1109
+ text = text[idx:]
1110
+ if text[0] == "\\":
1111
+ text = text[1:]
1112
+ return text
1113
+
1114
+
1115
+ def latex(tex):
1116
+ global frac_type
1117
+ result = sympy.latex(tex)
1118
+ result = result.replace(r'\frac', frac_type, -1).replace(r'\dfrac', frac_type, -1).replace(r'\tfrac', frac_type, -1)
1119
+ result = result.replace(r'\left[\begin{matrix}', r'\begin{bmatrix}', -1).replace(r'\end{matrix}\right]', r'\end{bmatrix}', -1)
1120
+ result = result.replace(r'\left', r'', -1).replace(r'\right', r'', -1)
1121
+ result = result.replace(r' )', r')', -1)
1122
+ result = result.replace(r'\log', r'\ln', -1)
1123
+ return result
1124
+
1125
+
1126
+ def latex2latex(tex):
1127
+ result = latex2sympy(tex)
1128
+ # if result is a list or tuple or dict
1129
+ if isinstance(result, list) or isinstance(result, tuple) or isinstance(result, dict):
1130
+ return latex(result)
1131
+ else:
1132
+ return latex(simplify(result.subs(variances).doit().doit()))
1133
+
1134
+
1135
+ # Set image value
1136
+ latex2latex('i=I')
1137
+ latex2latex('j=I')
1138
+ # set Identity(i)
1139
+ for i in range(1, 10):
1140
+ lh = sympy.Symbol(r'\bm{I}_' + str(i), real=False)
1141
+ lh_m = sympy.MatrixSymbol(r'\bm{I}_' + str(i), i, i)
1142
+ rh = sympy.Identity(i).as_mutable()
1143
+ variances[lh] = rh
1144
+ variances[lh_m] = rh
1145
+ var[str(lh)] = rh
1146
+
1147
+ if __name__ == '__main__':
1148
+ # latex2latex(r'A_1=\begin{bmatrix}1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8\end{bmatrix}')
1149
+ # latex2latex(r'b_1=\begin{bmatrix}1 \\ 2 \\ 3 \\ 4\end{bmatrix}')
1150
+ # tex = r"(x+2)|_{x=y+1}"
1151
+ # tex = r"\operatorname{zeros}(3)"
1152
+ tex = r"\operatorname{rows}(\begin{bmatrix}1 & 2 \\ 3 & 4\end{bmatrix})"
1153
+ # print("latex2latex:", latex2latex(tex))
1154
+ math = latex2sympy(tex)
1155
+ # math = math.subs(variances)
1156
+ print("latex:", tex)
1157
+ # print("var:", variances)
1158
+ print("raw_math:", math)
1159
+ # print("math:", latex(math.doit()))
1160
+ # print("math_type:", type(math.doit()))
1161
+ # print("shape:", (math.doit()).shape)
1162
+ print("cal:", latex2latex(tex))
latex2sympy/requirements.in ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ sympy
2
+ antlr4-python3-runtime
latex2sympy/requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.10
3
+ # by the following command:
4
+ #
5
+ # pip-compile requirements.in
6
+ #
7
+ antlr4-python3-runtime==4.11.1
8
+ # via -r requirements.in
9
+ mpmath==1.3.0
10
+ # via sympy
11
+ sympy==1.12
12
+ # via -r requirements.in
latex2sympy/sandbox/linalg_equations.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from latex2sympy import process_sympy
2
+ import sys
3
+ sys.path.append("..")
4
+
5
+ # latex = "2\\begin{pmatrix}1&1&1\\\\0&1&1\\\\0&0&1\\end{pmatrix}\\begin{pmatrix}1&1&1\\\\0&1&1\\\\0&0&1\\end{pmatrix}"
6
+ latex = "\\frac{a^{2} \\left(3 \\pi - 4 \\sin{\\left(\\pi \\right)} + \\frac{\\sin{\\left(2 \\pi \\right)}}{2}\\right)}{2}"
7
+ math = process_sympy(latex)
8
+
9
+ print(type(math))
10
+ print("latex: %s to math: %s" % (latex, math))
latex2sympy/sandbox/linalg_span.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from latex2sympy import process_sympy
2
+ import sys
3
+ sys.path.append("..")
4
+
5
+ latex = "\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix}"
6
+ math = process_sympy(latex)
7
+ print("latex: %s to math: %s" % (latex, math))
8
+
9
+ latex = "\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix},\\begin{pmatrix}4\\\\3\\\\1\\end{pmatrix}"
10
+ math = process_sympy(latex)
11
+ print("latex: %s to math: %s" % (latex, math))
12
+
13
+ latex = "[\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix},\\begin{pmatrix}4\\\\3\\\\1\\end{pmatrix}]"
14
+ math = process_sympy(latex)
15
+ print("latex: %s to math: %s" % (latex, math))
16
+
17
+ latex = "\\left\\{\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix},\\begin{pmatrix}4\\\\3\\\\1\\end{pmatrix}\\right\\}"
18
+ math = process_sympy(latex)
19
+ print("latex: %s to math: %s" % (latex, math))
latex2sympy/sandbox/matrix.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from latex2sympy import process_sympy
2
+ from sympy import *
3
+ import sys
4
+ sys.path.append("..")
5
+
6
+ theta = Symbol('theta', real=True)
7
+
8
+ latex = "\\begin{matrix}1&2\\\\3&4\\end{matrix}"
9
+ math = process_sympy(latex)
10
+ print("latex: %s to math: %s" % (latex, math))
11
+
12
+ latex = "\\begin{matrix}1&2\\\\3&4\\\\5&6\\end{matrix}"
13
+ math = process_sympy(latex)
14
+ print("latex: %s to math: %s" % (latex, math))
15
+
16
+ latex = "\\begin{matrix}1&2&3\\\\4&5&6\\\\7&8&9\\end{matrix}"
17
+ math = process_sympy(latex)
18
+ print("latex: %s to math: %s" % (latex, math))
19
+
20
+ latex = "\\begin{matrix}x^1&x^2&x^3\\\\y^1&y^2&y^3\\\\z^1&z^2&z^3\\end{matrix}"
21
+ math = process_sympy(latex)
22
+ print("latex: %s to math: %s" % (latex, math))
23
+
24
+ latex = "\\begin{matrix}x\\\\y\\end{matrix}"
25
+ math = process_sympy(latex)
26
+ print("latex: %s to math: %s" % (latex, math))
27
+
28
+ latex = "2\\cdot\\begin{matrix}x\\\\y\\end{matrix}"
29
+ math = process_sympy(latex)
30
+ print("latex: %s to math: %s" % (latex, math))
31
+
32
+ latex = "2\\cdot\\begin{matrix}x\\\\y\\end{matrix} + \\begin{matrix}2\\\\3\\end{matrix}"
33
+ math = process_sympy(latex)
34
+ print("latex: %s to math: %s" % (latex, math))
35
+
36
+ latex = "-2\\begin{matrix}1&2\\\\3&4\\end{matrix}"
37
+ math = process_sympy(latex)
38
+ print("latex: %s to math: %s" % (latex, math))
39
+
40
+ latex = "2\\cdot\\theta\\begin{matrix}x\\\\y\\end{matrix} + \\begin{matrix}2\\\\3\\end{matrix}"
41
+ math = process_sympy(latex)
42
+ print("latex: %s to math: %s" % (latex, math))
43
+
44
+ latex = "\\theta\\begin{matrix}1\\\\3\\end{matrix} - \\begin{matrix}-1\\\\2\\end{matrix}"
45
+ math = process_sympy(latex)
46
+ print("latex: %s to math: %s" % (latex, math))