[system] / trunk / pg / macros / contextLimitedPolynomial.pl Repository:
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 5517 Revision 5518
5 5
6=head3 Context("LimitedPolynomial") 6=head3 Context("LimitedPolynomial")
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;
44 $self->Error("Your answer doesn't look like a polynomial"); 57 $self->Error("Your answer doesn't look like a polynomial");
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#
155our @ISA = qw(LimitedPolynomial::BOP Parser::BOP::add); 177our @ISA = qw(LimitedPolynomial::BOP Parser::BOP::add);
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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9