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

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

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

Revision 6217 Revision 6218
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright 2000-2010 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright 2000-2010 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: pg/macros/contextPolynomialFactors.pl,v 1.1 2010/03/31 21:01:14 dpvc Exp $ 4# $CVSHeader: pg/macros/contextPolynomialFactors.pl,v 1.2 2010/03/31 21:45:42 dpvc Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 6# This program is free software; you can redistribute it and/or modify it under
7# the terms of either: (a) the GNU General Public License as published by the 7# the terms of either: (a) the GNU General Public License as published by the
8# Free Software Foundation; either version 2, or (at your option) any later 8# Free Software Foundation; either version 2, or (at your option) any later
9# version, or (b) the "Artistic License" which comes with this package. 9# version, or (b) the "Artistic License" which comes with this package.
53product or factors or only on a single factor at at time. These are 53product or factors or only on a single factor at at time. These are
54strictDivision and strictPowers. By default, strictDivisions is 0, so 54strictDivision and strictPowers. By default, strictDivisions is 0, so
55(x*(x+1))/3 is allowed, while strictPowers is 1, so (x*(x+1))^3 is not 55(x*(x+1))/3 is allowed, while strictPowers is 1, so (x*(x+1))^3 is not
56(it must be written x^3*(x+1)^3). 56(it must be written x^3*(x+1)^3).
57 57
58Finally, there is also a strict limited context that does not allow 58Finally, there is also a strict context that does not allow
59operations even within the coefficients. Select it using: 59operations even within the coefficients. Select it using:
60 60
61 Context("PolynomialFactors-Strict"); 61 Context("PolynomialFactors-Strict");
62 62
63In addition to disallowing operations within the coefficients, this 63In addition to disallowing operations within the coefficients, this
107 107
108package PolynomialFactors::BOP::multiply; 108package PolynomialFactors::BOP::multiply;
109our @ISA = qw(LimitedPolynomial::BOP::multiply); 109our @ISA = qw(LimitedPolynomial::BOP::multiply);
110 110
111sub checkPolynomial { 111sub checkPolynomial {
112 my $self = shift;
113 my ($l,$r) = ($self->{lop},$self->{rop}); 112 my $self = shift; my ($l,$r) = ($self->{lop},$self->{rop});
114 my $lOK = (LimitedPolynomial::isConstant($l) || $l->{isPower} || 113 my $lOK = (LimitedPolynomial::isConstant($l) || $l->{isPower} ||
115 $l->class eq 'Variable' || ($l->{isPoly} && $l->{isPoly} == 2)); 114 $l->class eq 'Variable' || ($l->{isPoly} && $l->{isPoly} == 2));
116 my $rOK = ($r->{isPower} || $r->class eq 'Variable'); 115 my $rOK = ($r->{isPower} || $r->class eq 'Variable');
117 return $self->checkExponents if $lOK and $rOK; 116 return $self->checkExponents if $lOK and $rOK;
118 $self->Error("Coefficients must come before variables or factors") 117 $self->Error("Coefficients must come before variables or factors")
134 $self->Error("Each factor can appear only once (combine like factors)") unless $factor eq "0"; 133 $self->Error("Each factor can appear only once (combine like factors)") unless $factor eq "0";
135 $self->Error("Only one constant coefficient or negation is allowed (combine them)"); 134 $self->Error("Only one constant coefficient or negation is allowed (combine them)");
136 } 135 }
137 $self->{factors}{$factor} = 1; 136 $self->{factors}{$factor} = 1;
138 } 137 }
138 delete $r->{factors};
139 $self->{isPoly} = 4; # product of factors 139 $self->{isPoly} = 4; # product of factors
140 return 1; 140 return 1;
141} 141}
142 142
143sub checkStrict { 143sub checkStrict {
149 149
150package PolynomialFactors::BOP::divide; 150package PolynomialFactors::BOP::divide;
151our @ISA = qw(LimitedPolynomial::BOP::divide); 151our @ISA = qw(LimitedPolynomial::BOP::divide);
152 152
153sub checkPolynomial { 153sub checkPolynomial {
154 my $self = shift;
155 my ($l,$r) = ($self->{lop},$self->{rop}); 154 my $self = shift; my ($l,$r) = ($self->{lop},$self->{rop});
156 $self->Error("In a polynomial, you can only divide by numbers") 155 $self->Error("In a polynomial, you can only divide by numbers")
157 unless LimitedPolynomial::isConstant($r); 156 unless LimitedPolynomial::isConstant($r);
158 if ($l->{isPoly} && $l->{isPoly} != 2) { 157 if ($l->{isPoly} && $l->{isPoly} != 2) {
159 $self->Error("You can only divide a single term or factor by a number") 158 $self->Error("You can only divide a single term or factor by a number")
160 if $l->{isPoly} == 3 || ($self->context->flag("strictDivision") && $self->{isPoly} != 1); 159 if $l->{isPoly} == 3 || ($self->context->flag("strictDivision") && $l->{isPoly} != 1);
161 PolynomialFactors::markFactor($l); 160 PolynomialFactors::markOpFactor($self,$l);
162 $self->Error("Only one constant multiple or fraction is allowed (combine them)") 161 $self->Error("Only one constant multiple or fraction is allowed (combine them)")
163 if $l->{factors}{0} && $self->context->flag("singleFactors"); 162 if $self->{factors}{0} && $self->context->flag("singleFactors");
164 $self->{factors} = $l->{factors}; delete $l->{factors};
165 $self->{factors}{0} = 1; # mark as constant multiple; 163 $self->{factors}{0} = 1; # mark as constant multiple;
166 $self->{isPoly} = 3; # factor over a number 164 $self->{isPoly} = 3; # factor over a number
167 } else { 165 } else {
168 $self->{isPoly} = $l->{isPoly}; 166 $self->{isPoly} = $l->{isPoly};
169 $self->{powers} = $l->{powers}; delete $l->{powers}; 167 $self->{powers} = $l->{powers}; delete $l->{powers};
176 174
177package PolynomialFactors::BOP::power; 175package PolynomialFactors::BOP::power;
178our @ISA = qw(LimitedPolynomial::BOP::power); 176our @ISA = qw(LimitedPolynomial::BOP::power);
179 177
180sub checkPolynomial { 178sub checkPolynomial {
181 my $self = shift;
182 my ($l,$r) = ($self->{lop},$self->{rop}); 179 my $self = shift; my ($l,$r) = ($self->{lop},$self->{rop});
183 $self->Error("Exponents must be constant in a polynomial") 180 $self->Error("Exponents must be constant in a polynomial")
184 unless LimitedPolynomial::isConstant($r); 181 unless LimitedPolynomial::isConstant($r);
185 my $n = Parser::Evaluate($r); 182 my $n = Parser::Evaluate($r);
186 $r->Error($$Value::context->{error}{message}) if $$Value::context->{error}{flag}; 183 $r->Error($$Value::context->{error}{message}) if $$Value::context->{error}{flag};
187 $n = $n->value; 184 $n = $n->value;
188 $self->Error("Exponents must be positive integers in a polynomial") 185 $self->Error("Exponents must be positive integers in a polynomial")
189 unless $n > 0 && $n == int($n); 186 unless $n > 0 && $n == int($n);
190 if ($l->{isPoly}) { 187 if ($l->{isPoly}) {
191 $self->Error("You can only raise a single term or factor to a power") 188 $self->Error("You can only raise a single term or factor to a power")
192 if $l->{isPoly} > 2 && $self->context->flag("strictPowers"); 189 if $l->{isPoly} > 2 && $self->context->flag("strictPowers");
193 PolynomialFactors::markFactor($l); 190 PolynomialFactors::markOpFactor($self,$l);
194 $self->{factors} = $l->{factors}; delete $l->{factors};
195 $self->{isPoly} = 5; # factor to a power 191 $self->{isPoly} = 5; # factor to a power
196 } else { 192 } else {
197 LimitedPolynomial::markPowers($l); 193 LimitedPolynomial::markPowers($l);
198 $self->{exponents} = $l->{exponents}; delete $l->{exponents}; 194 $self->{exponents} = $l->{exponents}; delete $l->{exponents};
199 foreach my $i (@{$self->{exponents}}) {$i = $n if $i} 195 foreach my $i (@{$self->{exponents}}) {$i = $n if $i}
214 210
215sub checkPolynomial { 211sub checkPolynomial {
216 my $self = shift; my $op = $self->{op}; 212 my $self = shift; my $op = $self->{op};
217 if ($op->{isPoly} && $self->context->flag("singleFactors")) { 213 if ($op->{isPoly} && $self->context->flag("singleFactors")) {
218 $self->Error("Double negatives are not allowed") if $op->{isPoly} == 2; 214 $self->Error("Double negatives are not allowed") if $op->{isPoly} == 2;
219 $self->Error("Only one factor or constant can be negated") 215 $self->Error("Only one factor or constant can be negated") if $op->{isPoly} == 4;
220 if $op->{isPoly} != 1 && $op->{isPoly} != 5;
221 } 216 }
222 PolynomialFactors::markFactor($op); 217 PolynomialFactors::markOpFactor($self,$op);
223 $self->{factors} = $op->{factors}; delete $op->{factors};
224 $self->{factors}{0} = 1; # mark as constant multiple 218 $self->{factors}{0} = 1; # mark as constant multiple
225 return 1; 219 return 1;
226} 220}
227 221
228############################################## 222##############################################
241 } elsif ($self->{isPoly} && $self->{isPoly} == 1) { 235 } elsif ($self->{isPoly} && $self->{isPoly} == 1) {
242 $self->{factors}{$self->string} = 1; 236 $self->{factors}{$self->string} = 1;
243 } elsif ($self->{isPower}) { 237 } elsif ($self->{isPower}) {
244 $self->{factors}{$self->{lop}->string} = 1; 238 $self->{factors}{$self->{lop}->string} = 1;
245 } 239 }
240}
241
242sub markOpFactor {
243 my $self = shift; my $op = shift;
244 markFactor($op);
245 $self->{factors} = $op->{factors};
246 delete $op->{factors};
246} 247}
247 248
248sub Init { 249sub Init {
249 # 250 #
250 # Build the new context that calls the 251 # Build the new context that calls the

Legend:
Removed from v.6217  
changed lines
  Added in v.6218

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9