[system] / trunk / pg / macros / contextLimitedPolynomial.pl Repository: Repository Listing bbplugincoursesdistsnplrochestersystemwww

# Diff of /trunk/pg/macros/contextLimitedPolynomial.pl

Revision 5517 Revision 5518
5 5
7 7
8 ########################################################## 8 ##########################################################
9 # 9 #
10 # Implements a context in which students can only 10 # Implements a context in which students can only enter (expanded)
11 # enter (expanded) polynomials (i.e., sums of multiples 11 # polynomials (i.e., sums of multiples of powers of x).
12 # of powers of x).
13 # 12 #
14 # Select the context using: 13 # Select the context using:
15 # 14 #
16 # Context("LimitedPolynomial"); 15 # Context("LimitedPolynomial");
17 # 16 #
18 # If you set the "singlePowers" flag, then only one monomial of 17 # If you set the "singlePowers" flag, then only one monomial of each
19 # each degree can be included in the polynomial: 18 # degree can be included in the polynomial:
20 # 19 #
21 # Context("LimitedPolynomial")->flags->set(singlePowers=>1); 20 # Context("LimitedPolynomial")->flags->set(singlePowers=>1);
21 #
22 # There is also a strict limited context that does not allow
23 # operations even within the coefficients. Select it using:
24 #
25 # Context("LimitedPolynomial-Strict");
26 #
27 # In addition to disallowing operations within the coefficients,
28 # this context does not reduce constant operations (since they are
29 # not allowed), and sets the singlePowers flag automatically. In
30 # addition, it disables all the functions, though they can be
31 # re-enabled, if needed.
22 # 32 #
23 33
24=cut 34=cut
25 35
26################################################## 36##################################################
36# 46#
37sub _check { 47sub _check {
38 my \$self = shift; 48 my \$self = shift;
39 my \$super = ref(\$self); \$super =~ s/LimitedPolynomial/Parser/; 49 my \$super = ref(\$self); \$super =~ s/LimitedPolynomial/Parser/;
40 &{\$super."::_check"}(\$self); 50 &{\$super."::_check"}(\$self);
41 return if LimitedPolynomial::isConstant(\$self->{lop}) && 51 if (LimitedPolynomial::isConstant(\$self->{lop}) &&
42 LimitedPolynomial::isConstant(\$self->{rop}); 52 LimitedPolynomial::isConstant(\$self->{rop})) {
53 \$self->checkStrict if \$self->context->flag("strictCoefficients");
54 return;
55 }
43 return if \$self->checkPolynomial; 56 return if \$self->checkPolynomial;
45} 58}
46 59
47# 60#
93 } 106 }
94 delete \$r->{powers}; 107 delete \$r->{powers};
95 return 1; 108 return 1;
96} 109}
97 110
111#
112# Report an error when both operands are constants
113# and strictCoefficients is in effect.
114#
115sub checkStrict {
116 my \$self = shift;
117 \$self->Error("Can't use '%s' between constants",\$self->{bop});
118}
119
98################################################## 120##################################################
99 121
100package LimitedPolynomial; 122package LimitedPolynomial;
101 123
102# 124#
156 178
157sub checkPolynomial { 179sub checkPolynomial {
158 my \$self = shift; 180 my \$self = shift;
159 my (\$l,\$r) = (\$self->{lop},\$self->{rop}); 181 my (\$l,\$r) = (\$self->{lop},\$self->{rop});
160 \$self->Error("Addition is allowed only between monomials") 182 \$self->Error("Addition is allowed only between monomials") if \$r->{isPoly};
161 if \$r->{isPoly};
162 \$self->checkPowers; 183 \$self->checkPowers;
184}
185
186sub checkStrict {
187 my \$self = shift;
188 \$self->Error("You can only use addition for the terms of a polynomial",\$self->{bop});
163} 189}
164 190
165############################################## 191##############################################
166 192
167package LimitedPolynomial::BOP::subtract; 193package LimitedPolynomial::BOP::subtract;
168our @ISA = qw(LimitedPolynomial::BOP Parser::BOP::subtract); 194our @ISA = qw(LimitedPolynomial::BOP Parser::BOP::subtract);
169 195
170sub checkPolynomial { 196sub checkPolynomial {
171 my \$self = shift; 197 my \$self = shift;
172 my (\$l,\$r) = (\$self->{lop},\$self->{rop}); 198 my (\$l,\$r) = (\$self->{lop},\$self->{rop});
173 \$self->Error("Subtraction is only allowed between monomials") 199 \$self->Error("Subtraction is allowed only between monomials") if \$r->{isPoly};
174 if \$r->{isPoly};
175 \$self->checkPowers; 200 \$self->checkPowers;
201}
202
203sub checkStrict {
204 my \$self = shift;
205 \$self->Error("You can only use subtraction between the terms of a polynomial",\$self->{bop});
176} 206}
177 207
178############################################## 208##############################################
179 209
180package LimitedPolynomial::BOP::multiply; 210package LimitedPolynomial::BOP::multiply;
188 my \$rOK = (\$r->{isPower} || \$r->class eq 'Variable'); 218 my \$rOK = (\$r->{isPower} || \$r->class eq 'Variable');
189 return \$self->checkExponents if \$lOK and \$rOK; 219 return \$self->checkExponents if \$lOK and \$rOK;
190 \$self->Error("Coefficients must come before variables in a polynomial") 220 \$self->Error("Coefficients must come before variables in a polynomial")
191 if LimitedPolynomial::isConstant(\$r) && (\$l->{isPower} || \$l->class eq 'Variable'); 221 if LimitedPolynomial::isConstant(\$r) && (\$l->{isPower} || \$l->class eq 'Variable');
192 \$self->Error("Multiplication can only be used between coefficients and variables"); 222 \$self->Error("Multiplication can only be used between coefficients and variables");
223}
224
225sub checkStrict {
226 my \$self = shift;
227 \$self->Error("You can only use '%s' between a coefficent and a variable in a polynomial",\$self->{bop});
193} 228}
194 229
195############################################## 230##############################################
196 231
197package LimitedPolynomial::BOP::divide; 232package LimitedPolynomial::BOP::divide;
206 if \$l->{isPoly} && \$l->{isPoly} == 1; 241 if \$l->{isPoly} && \$l->{isPoly} == 1;
207 \$self->{isPoly} = \$l->{isPoly}; 242 \$self->{isPoly} = \$l->{isPoly};
208 \$self->{powers} = \$l->{powers}; delete \$l->{powers}; 243 \$self->{powers} = \$l->{powers}; delete \$l->{powers};
209 \$self->{exponents} = \$l->{exponents}; delete \$l->{exponents}; 244 \$self->{exponents} = \$l->{exponents}; delete \$l->{exponents};
210 return 1; 245 return 1;
246}
247
248sub checkStrict {
249 my \$self = shift;
250 \$self->Error("You can only use '%s' to form fractions",\$self->{bop}) if \$self->{lop}->class eq 'BOP';
211} 251}
212 252
213############################################## 253##############################################
214 254
215package LimitedPolynomial::BOP::power; 255package LimitedPolynomial::BOP::power;
230 LimitedPolynomial::markPowers(\$l); 270 LimitedPolynomial::markPowers(\$l);
231 \$self->{exponents} = \$l->{exponents}; delete \$l->{exponents}; 271 \$self->{exponents} = \$l->{exponents}; delete \$l->{exponents};
232 foreach my \$i (@{\$self->{exponents}}) {\$i = \$n if \$i} 272 foreach my \$i (@{\$self->{exponents}}) {\$i = \$n if \$i}
233 \$self->{isPower} = 1; 273 \$self->{isPower} = 1;
234 return 1; 274 return 1;
275}
276
277sub checkStrict {
278 my \$self = shift;
279 \$self->Error("You can only use powers of a variable in a polynomial");
235} 280}
236 281
237############################################## 282##############################################
238############################################## 283##############################################
239# 284#
364 # 409 #
365 # Don't convert -ax-b to -(ax+b), etc. 410 # Don't convert -ax-b to -(ax+b), etc.
366 # 411 #
367 \$context->reduction->set("(-x)-y"=>0); 412 \$context->reduction->set("(-x)-y"=>0);
368 413
414 #
415 # A context where coefficients can't include operations
416 #
417 \$context = \$main::context{"LimitedPolynomial-Strict"} = \$context->copy;
418 \$context->flags->set(strictCoefficients=>1, singelPowers=>1, reduceConstants=>0);
419 \$context->functions->disable("All"); # can be re-enabled if needed
420
369 main::Context("LimitedPolynomial"); ### FIXME: probably should require author to set this explicitly 421 main::Context("LimitedPolynomial"); ### FIXME: probably should require author to set this explicitly
370} 422}
371 423
3721; 4241;

Legend:
 Removed from v.5517 changed lines Added in v.5518