Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +2 -0
- .gitignore +185 -0
- Chain_Of_Thought_Metric/length_of_answer.py +146 -0
- Chain_Of_Thought_Metric/metric.py +172 -0
- Chain_Of_Thought_Metric/tools.py +80 -0
- Following_Budget_Ratio.png +0 -0
- GPU_hunter.py +57 -0
- LICENSE +21 -0
- README.md +52 -0
- api_test.py +448 -0
- copy_backup.py +36 -0
- data/aime24/aime24.parquet +3 -0
- data/amc23/amc23.parquet +3 -0
- data/carp_en/demo.json +8 -0
- data/math500/math500_RL.parquet +3 -0
- data/math500_answer_prompt/get_answer_prompt.py +24 -0
- data/minerva_math/README.md +2 -0
- data/olympiadbench/test.json +0 -0
- data/trans_parquet.py +28 -0
- data_loader.py +85 -0
- eval_tools.py +470 -0
- evaluate.py +117 -0
- examples.py +378 -0
- grader.py +395 -0
- latex2sympy/.coveragerc +31 -0
- latex2sympy/.gitignore +132 -0
- latex2sympy/LICENSE.txt +21 -0
- latex2sympy/PS.g4 +638 -0
- latex2sympy/README.md +196 -0
- latex2sympy/__init__.py +1 -0
- latex2sympy/antlr-4.11.1-complete.jar +3 -0
- latex2sympy/asciimath_printer.py +50 -0
- latex2sympy/description.txt +152 -0
- latex2sympy/dev-requirements.in +8 -0
- latex2sympy/dev-requirements.txt +60 -0
- latex2sympy/gen/PS.interp +462 -0
- latex2sympy/gen/PS.tokens +357 -0
- latex2sympy/gen/PSLexer.interp +0 -0
- latex2sympy/gen/PSLexer.py +0 -0
- latex2sympy/gen/PSLexer.tokens +357 -0
- latex2sympy/gen/PSListener.py +573 -0
- latex2sympy/gen/PSParser.py +0 -0
- latex2sympy/gen/__init__.py +0 -0
- latex2sympy/icon.png +0 -0
- latex2sympy/latex2sympy2.py +1162 -0
- latex2sympy/requirements.in +2 -0
- latex2sympy/requirements.txt +12 -0
- latex2sympy/sandbox/linalg_equations.py +10 -0
- latex2sympy/sandbox/linalg_span.py +19 -0
- 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 |
+

|
| 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))
|