mathhook_core/core/polynomial/educational/
division.rs1use super::super::arithmetic::PolynomialArithmetic;
4use super::super::classification::PolynomialClassification;
5use super::super::properties::PolynomialProperties;
6use super::create_explanation;
7use crate::core::{Expression, Symbol};
8use crate::educational::step_by_step::{Step, StepByStepExplanation};
9
10pub fn explain_poly_division_impl(
11 expr: &Expression,
12 divisor: &Expression,
13 var: &Symbol,
14) -> StepByStepExplanation {
15 let mut steps = Vec::new();
16
17 steps.push(Step {
18 title: "Polynomial Division".to_owned(),
19 description: format!(
20 "Divide {} by {} with respect to {}",
21 expr,
22 divisor,
23 var.name()
24 ),
25 expression: expr.clone(),
26 rule_applied: "Initial".to_owned(),
27 latex: None,
28 });
29
30 if !expr.is_polynomial_in(std::slice::from_ref(var)) {
31 steps.push(Step {
32 title: "Not a Polynomial".to_owned(),
33 description: format!(
34 "The dividend {} is not a polynomial in {}",
35 expr,
36 var.name()
37 ),
38 expression: expr.clone(),
39 rule_applied: "Validation".to_owned(),
40 latex: None,
41 });
42 return create_explanation(expr.clone(), expr.clone(), steps);
43 }
44
45 if !divisor.is_polynomial_in(std::slice::from_ref(var)) {
46 steps.push(Step {
47 title: "Not a Polynomial".to_owned(),
48 description: format!(
49 "The divisor {} is not a polynomial in {}",
50 divisor,
51 var.name()
52 ),
53 expression: divisor.clone(),
54 rule_applied: "Validation".to_owned(),
55 latex: None,
56 });
57 return create_explanation(expr.clone(), expr.clone(), steps);
58 }
59
60 let dividend_deg = expr.degree(var).unwrap_or(0);
61 let divisor_deg = divisor.degree(var).unwrap_or(0);
62
63 steps.push(Step {
64 title: "Identify Degrees".to_owned(),
65 description: format!(
66 "Dividend degree: {}\nDivisor degree: {}",
67 dividend_deg, divisor_deg
68 ),
69 expression: expr.clone(),
70 rule_applied: "Degree Computation".to_owned(),
71 latex: None,
72 });
73
74 if divisor.is_zero() {
75 steps.push(Step {
76 title: "Division by Zero".to_owned(),
77 description: "Cannot divide by zero polynomial".to_owned(),
78 expression: divisor.clone(),
79 rule_applied: "Error".to_owned(),
80 latex: None,
81 });
82 return create_explanation(expr.clone(), expr.clone(), steps);
83 }
84
85 if divisor_deg > dividend_deg {
86 steps.push(Step {
87 title: "Divisor Degree Too High".to_owned(),
88 description: format!(
89 "Since divisor degree ({}) > dividend degree ({}), \
90 quotient = 0 and remainder = dividend",
91 divisor_deg, dividend_deg
92 ),
93 expression: expr.clone(),
94 rule_applied: "Degree Comparison".to_owned(),
95 latex: None,
96 });
97
98 steps.push(Step {
99 title: "Result".to_owned(),
100 description: format!("Quotient: 0\nRemainder: {}", expr),
101 expression: Expression::integer(0),
102 rule_applied: "Final".to_owned(),
103 latex: None,
104 });
105
106 return create_explanation(expr.clone(), Expression::integer(0), steps);
107 }
108
109 steps.push(Step {
110 title: "Long Division Algorithm".to_owned(),
111 description: "Repeatedly divide leading terms until remainder degree < divisor degree"
112 .to_owned(),
113 expression: expr.clone(),
114 rule_applied: "Algorithm".to_owned(),
115 latex: None,
116 });
117
118 match expr.poly_div(divisor, var) {
119 Ok((quotient, remainder)) => {
120 steps.push(Step {
121 title: "Division Complete".to_owned(),
122 description: format!(
123 "Quotient: {}\nRemainder: {}\n\nVerification: {} = ({}) * ({}) + ({})",
124 quotient, remainder, expr, divisor, quotient, remainder
125 ),
126 expression: quotient.clone(),
127 rule_applied: "Result".to_owned(),
128 latex: None,
129 });
130
131 create_explanation(expr.clone(), quotient, steps)
132 }
133 Err(e) => {
134 steps.push(Step {
135 title: "Error".to_owned(),
136 description: format!("Division failed: {}", e),
137 expression: expr.clone(),
138 rule_applied: "Error".to_owned(),
139 latex: None,
140 });
141
142 create_explanation(expr.clone(), expr.clone(), steps)
143 }
144 }
145}