mirror of
https://github.com/open-thought/reasoning-gym.git
synced 2026-04-19 12:58:07 +00:00
125 lines
4.6 KiB
Python
125 lines
4.6 KiB
Python
"""
|
|
Simple equations exercise that generates and solves linear equations with one variable.
|
|
"""
|
|
|
|
from typing import Dict, Any
|
|
from sympy import Symbol, solve, parse_expr, Eq
|
|
|
|
class SimpleEquationsExercise:
|
|
"""Exercise generator for simple equations with one variable."""
|
|
|
|
def __init__(self):
|
|
self.curriculum = None
|
|
|
|
def generate(self, curriculum: Any) -> Dict[str, Any]:
|
|
"""
|
|
Generate a simple equation problem using the curriculum.
|
|
|
|
Returns:
|
|
Dict containing:
|
|
- question: str (e.g. "Find the value of x in the equation: 3*x + 2 = 4*x - 1")
|
|
- answer: str (the solution value, e.g. "3")
|
|
- metadata: dict with details (equation, variable, etc.)
|
|
"""
|
|
self.curriculum = curriculum
|
|
template = curriculum.get_template(curriculum.rng)
|
|
return template.eval(self, curriculum.rng)
|
|
|
|
def _parse_expression(self, metadata: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""
|
|
Parse the template metadata into structured data.
|
|
|
|
The metadata structure is expected to be:
|
|
{
|
|
"lhs": {
|
|
"term_0": {
|
|
"sign": str, # "" or "-"
|
|
"coeff": str, # coefficient value with "*" if needed
|
|
"variable": str # variable name or empty
|
|
},
|
|
"term_1": {...}, # Same structure as term_0
|
|
...,
|
|
"op_0": str, # "+" or "-" between terms
|
|
"op_1": str, # More operators if needed
|
|
...
|
|
},
|
|
"rhs": { # Same structure as lhs
|
|
...
|
|
},
|
|
"variable": {
|
|
"var": str # The variable name used in the equation
|
|
}
|
|
}
|
|
|
|
Args:
|
|
metadata: Raw metadata from template evaluation
|
|
Returns:
|
|
Dictionary containing:
|
|
- lhs_terms: List[str] of formatted term strings for left side
|
|
- rhs_terms: List[str] of formatted term strings for right side
|
|
- lhs_operators: List[str] of operators between left terms
|
|
- rhs_operators: List[str] of operators between right terms
|
|
- variable: str, the variable name used
|
|
"""
|
|
def parse_side(side_parts: Dict[str, Any]) -> tuple[list, list]:
|
|
"""Helper to parse one side of the equation."""
|
|
terms = []
|
|
operators = []
|
|
i = 0
|
|
while f"term_{i}" in side_parts:
|
|
term_dict = side_parts[f"term_{i}"]
|
|
terms.append("".join(term_dict[k] for k in ("sign", "coeff", "variable")))
|
|
if f"op_{i}" in side_parts:
|
|
operators.append(side_parts[f"op_{i}"])
|
|
i += 1
|
|
return terms, operators
|
|
|
|
# Parse both sides of the equation
|
|
lhs_terms, lhs_operators = parse_side(metadata["lhs"])
|
|
rhs_terms, rhs_operators = parse_side(metadata["rhs"])
|
|
|
|
return {
|
|
"lhs_terms": lhs_terms,
|
|
"rhs_terms": rhs_terms,
|
|
"lhs_operators": lhs_operators,
|
|
"rhs_operators": rhs_operators,
|
|
"variable": metadata["variable"]["var"]
|
|
}
|
|
|
|
def _evaluate_expression(self, parsed: Dict[str, Any]) -> str:
|
|
"""
|
|
Evaluate the equation and find its solution.
|
|
|
|
Args:
|
|
parsed: Dictionary containing parsed expression data
|
|
Returns:
|
|
String representation of the solution
|
|
"""
|
|
# Create sympy symbol from parsed variable
|
|
var = Symbol(parsed["variable"])
|
|
|
|
# Build left and right expressions
|
|
def build_expr(terms: list, operators: list) -> str:
|
|
"""Helper to build expression string from terms and operators."""
|
|
expr = terms[0]
|
|
for i, op in enumerate(operators):
|
|
expr = f"{expr} {op} {terms[i + 1]}"
|
|
return expr
|
|
|
|
lhs_expr = build_expr(parsed["lhs_terms"], parsed["lhs_operators"])
|
|
rhs_expr = build_expr(parsed["rhs_terms"], parsed["rhs_operators"])
|
|
|
|
try:
|
|
# Parse both sides into sympy expressions
|
|
lhs = parse_expr(lhs_expr, local_dict={parsed["variable"]: var})
|
|
rhs = parse_expr(rhs_expr, local_dict={parsed["variable"]: var})
|
|
|
|
# Solve the equation
|
|
solution = solve(Eq(lhs, rhs), var)
|
|
|
|
# Convert to float and return as string
|
|
if solution:
|
|
return str(float(solution[0]))
|
|
return ""
|
|
except Exception as e:
|
|
return f"Error solving equation: {lhs_expr} = {rhs_expr}\nError: {str(e)}"
|