| import re |
| from .explainer_types import ExplainerResult, ExplainerScaffold |
|
|
|
|
| _ALGEBRA_PATTERNS = [ |
| r"=", |
| r"\bsolve\b", |
| r"\bequation\b", |
| r"\bexpression\b", |
| r"\bvalue of\b", |
| r"\bwhat is x\b", |
| r"\bwhat is y\b", |
| r"\bvariable\b", |
| ] |
|
|
|
|
| def _looks_like_algebra_question(text: str) -> bool: |
| low = (text or "").lower() |
|
|
| if re.search(r"\b[xyzab]\b", low) and "=" in low: |
| return True |
| if any(re.search(p, low) for p in _ALGEBRA_PATTERNS): |
| return True |
| return False |
|
|
|
|
| def _infer_algebra_subtype(text: str) -> str: |
| low = (text or "").lower() |
|
|
| if any(k in low for k in ["system", "simultaneous", "x and y", "two equations"]): |
| return "system" |
| if any(k in low for k in ["inequality", "<", ">", "at least", "at most", "no more than"]): |
| return "inequality" |
| if any(k in low for k in ["quadratic", "squared", "^2", "x2", "root", "factor"]): |
| return "quadratic" |
| if any(k in low for k in ["expression", "value of 2x", "value of x +", "in terms of"]): |
| return "expression_evaluation" |
| if "=" in low: |
| return "linear_equation" |
| return "generic_algebra" |
|
|
|
|
| def explain_algebra_question(text: str): |
| if not _looks_like_algebra_question(text): |
| return None |
|
|
| subtype = _infer_algebra_subtype(text) |
| low = (text or "").lower() |
|
|
| result = ExplainerResult( |
| understood=True, |
| topic="algebra", |
| summary="This is an algebra problem. The main goal is to translate the wording into a clean symbolic relationship and isolate the requested quantity step by step.", |
| asks_for="the value of the variable or the requested expression built from it", |
| plain_english="Algebra questions usually become easier once you write one clean equation and then reverse the operations in order.", |
| ) |
|
|
| scaffold = ExplainerScaffold( |
| concept="Algebra represents unknown quantities symbolically, then uses valid transformations to isolate or compare them.", |
| ask="Identify the unknown, identify the governing relationship, and check whether the question wants the variable itself or an expression built from it.", |
| target="Set up the simplest correct equation or relation before manipulating it.", |
| answer_hidden=True, |
| solution_path_type=subtype, |
| ) |
|
|
| result.givens = [ |
| "A symbolic relationship or equation is implied by the wording.", |
| ] |
| if "=" in low: |
| result.givens.append("An equals sign or equation structure is present.") |
|
|
| result.relationships = [ |
| "Both sides of an equation must stay balanced.", |
| "Each algebra step should simplify or isolate the target quantity.", |
| ] |
| result.needed_concepts = [ |
| "equation balancing", |
| "inverse operations", |
| "checking what the question actually asks for", |
| ] |
| result.trap_notes = [ |
| "Moving terms across the equals sign incorrectly.", |
| "Trying to isolate the variable before simplifying.", |
| "Finding x and forgetting the question asks for something like 2x or x + 3.", |
| ] |
| result.strategy_hint = "Rewrite the relationship as one clean equation before doing any manipulation." |
|
|
| result.teaching_points = [ |
| "Most algebra errors happen before the solving starts: either the variable is misdefined, or the equation is set up incorrectly.", |
| "A clean equation makes the solving steps much easier.", |
| "You should always check whether the question asks for x itself or for something derived from x.", |
| ] |
|
|
| if subtype == "linear_equation": |
| scaffold.setup_actions = [ |
| "Identify the unknown and write the equation cleanly.", |
| "Simplify each side if needed.", |
| "Undo operations in a logical order to isolate the variable.", |
| ] |
| scaffold.intermediate_steps = [ |
| "Combine like terms first when possible.", |
| "Move variable terms and constant terms carefully.", |
| "Check whether the final result should be the variable or a substituted expression.", |
| ] |
| scaffold.first_move = "Rewrite the relationship as one clean equation if it is not already in that form." |
| scaffold.next_hint = "Simplify both sides before isolating the variable." |
| scaffold.variables_to_define = [ |
| "Let the unknown quantity be x if the question has not already named it.", |
| ] |
| scaffold.equations_to_form = [ |
| "Build one equation from the stated relationship.", |
| ] |
| scaffold.key_operations = [ |
| "Simplify", |
| "undo addition/subtraction", |
| "undo multiplication/division", |
| ] |
| scaffold.hint_ladder = [ |
| "What operation is attached to the variable?", |
| "What inverse operation would undo it?", |
| "Apply that same operation to both sides.", |
| ] |
|
|
| elif subtype == "system": |
| scaffold.setup_actions = [ |
| "Identify the separate equations and unknowns.", |
| "Decide whether substitution or elimination is the cleaner method.", |
| "Reduce the system to one variable before solving completely.", |
| ] |
| scaffold.intermediate_steps = [ |
| "Make one variable easy to substitute, or align coefficients for elimination.", |
| "After finding one variable, substitute back carefully.", |
| "Check whether the question asks for one variable, both variables, or a combination of them.", |
| ] |
| scaffold.first_move = "Choose one variable to eliminate or substitute." |
| scaffold.next_hint = "Turn the system into a single-variable equation before solving." |
| scaffold.equations_to_form = [ |
| "Use the two given equations together to reduce to one unknown.", |
| ] |
| scaffold.key_operations = [ |
| "substitute", |
| "eliminate", |
| "back-substitute", |
| ] |
| scaffold.hint_ladder = [ |
| "Which variable looks easier to isolate?", |
| "Can you align coefficients for elimination?", |
| "After finding one variable, plug it back into the other equation.", |
| ] |
|
|
| elif subtype == "inequality": |
| scaffold.setup_actions = [ |
| "Translate the condition into an inequality.", |
| "Manipulate it like an equation, but track the inequality direction carefully.", |
| "Reverse the sign only if multiplying or dividing by a negative number.", |
| ] |
| scaffold.intermediate_steps = [ |
| "Simplify both sides first if possible.", |
| "Isolate the variable systematically.", |
| "Interpret the final solution set in the form the question wants.", |
| ] |
| scaffold.first_move = "Set up the inequality carefully from the wording." |
| scaffold.next_hint = "Solve it step by step, watching for any operation that would reverse the sign." |
| scaffold.key_operations = [ |
| "translate wording to an inequality", |
| "simplify", |
| "watch for sign reversal with negatives", |
| ] |
| scaffold.hint_ladder = [ |
| "What phrase tells you the direction of the inequality?", |
| "Can you simplify both sides first?", |
| "Did you divide or multiply by a negative at any point?", |
| ] |
|
|
| elif subtype == "quadratic": |
| scaffold.setup_actions = [ |
| "Rewrite the equation so one side is zero if needed.", |
| "Look for factoring, structure, or another simplifying method.", |
| "Treat each factor or case carefully once the equation is structured properly.", |
| ] |
| scaffold.intermediate_steps = [ |
| "Factor if the form allows it.", |
| "Otherwise identify another clean solving route.", |
| "Check whether all resulting values are allowed in the original context.", |
| ] |
| scaffold.first_move = "Put the expression into a standard structured form before solving." |
| scaffold.next_hint = "Then look for a factorable pattern or another clean route." |
| scaffold.key_operations = [ |
| "standardize the expression", |
| "factor or use structure", |
| "check all roots back in context", |
| ] |
| scaffold.hint_ladder = [ |
| "Can you move everything to one side first?", |
| "Does the expression factor neatly?", |
| "Do all candidate solutions actually fit the original question?", |
| ] |
|
|
| elif subtype == "expression_evaluation": |
| scaffold.setup_actions = [ |
| "Find the variable or relationship first.", |
| "Only then substitute into the requested expression.", |
| "Simplify the final expression carefully.", |
| ] |
| scaffold.intermediate_steps = [ |
| "Do not stop when you find the variable unless that is exactly what the question asks.", |
| "Preserve parentheses during substitution.", |
| "Check whether there is a shortcut using the given relationship directly.", |
| ] |
| scaffold.first_move = "Work out whether you need to solve for the variable first or can rewrite the target expression directly." |
| scaffold.next_hint = "Once the relationship is clear, substitute only into the exact expression the question asks for." |
| scaffold.key_operations = [ |
| "solve or rewrite the relationship", |
| "substitute carefully", |
| "simplify the requested expression", |
| ] |
| scaffold.hint_ladder = [ |
| "What expression does the question actually want?", |
| "Do you already have enough information to rewrite that expression?", |
| "Only substitute after the target expression is clear.", |
| ] |
|
|
| else: |
| scaffold.setup_actions = [ |
| "Define the unknown clearly.", |
| "Translate the wording into a symbolic relationship.", |
| "Manipulate the relationship only after the setup is clean.", |
| ] |
| scaffold.intermediate_steps = [ |
| "Simplify before isolating.", |
| "Keep track of what the question actually asks for.", |
| "Check the final quantity against the prompt.", |
| ] |
| scaffold.first_move = "Start by translating the words into one clean symbolic statement." |
| scaffold.next_hint = "Then simplify the structure before solving." |
| scaffold.key_operations = [ |
| "translate", |
| "simplify", |
| "isolate", |
| ] |
| scaffold.hint_ladder = [ |
| "What is the unknown?", |
| "What relationship connects the quantities?", |
| "What is the cleanest first algebra step?", |
| ] |
|
|
| result.scaffold = scaffold |
| result.meta = { |
| "intent": "explain_question", |
| "bridge_ready": True, |
| "hint_style": "step_ready", |
| "subtype": subtype, |
| } |
| return result |