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

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

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

Revision 5556 Revision 5917
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork2/lib/WeBWorK.pm,v 1.100 2007/08/13 22:59:53 sh002i Exp $ 4# $CVSHeader: pg/macros/parserFormulaUpToConstant.pl,v 1.18 2008/09/16 03:23:54 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.
147 my $n00 = $context->variables->get("n00"); 147 my $n00 = $context->variables->get("n00");
148 $context->variables->add(n00=>'Parameter') unless $n00 and $n00->{parameter}; 148 $context->variables->add(n00=>'Parameter') unless $n00 and $n00->{parameter};
149 my $n01 = $context->variables->get("n01"); 149 my $n01 = $context->variables->get("n01");
150 $context->variables->add(n01=>'Parameter') unless $n01 and $n01->{parameter}; 150 $context->variables->add(n01=>'Parameter') unless $n01 and $n01->{parameter};
151 $f->{adapt} = $f + "(n00-$n)$f->{constant} + n01"; 151 $f->{adapt} = $f + "(n00-$n)$f->{constant} + n01";
152
152 return bless $f, $class; 153 return bless $f, $class;
153} 154}
154 155
155################################################## 156##################################################
156# 157#
173 # 174 #
174 $r = $r->substitute($r->{constant}=>$l->{constant}) unless $r->{constant} eq $l->{constant}; 175 $r = $r->substitute($r->{constant}=>$l->{constant}) unless $r->{constant} eq $l->{constant};
175 # 176 #
176 # Compare with adaptive parameters to see if $l + n0 C = $r for some n0. 177 # Compare with adaptive parameters to see if $l + n0 C = $r for some n0.
177 # 178 #
178 return -1 unless $l->{adapt} == $r; 179 my $adapt = $l->adapt;
180 my $equal = $adapt->cmp_compare($r,{});
181 $self->{adapt} = $self->{adapt}->inherit($adapt); # save the adapted value's flags
182 return -1 unless $equal;
179 # 183 #
180 # Check that n0 is non-zero (i.e., there is a multiple of C in the student answer) 184 # Check that n0 is non-zero (i.e., there is a multiple of C in the student answer)
181 # (remember: return value of 0 is equal, and non-zero is unequal) 185 # (remember: return value of 0 is equal, and non-zero is unequal)
182 # 186 #
183 return abs($context->variables->get("n00")->{value}) < $context->flag("zeroLevelTol"); 187 return abs($context->variables->get("n00")->{value}) < $context->flag("zeroLevelTol");
188}
189
190#
191# Return the {adapt} formula with test points adjusted
192#
193sub adapt {
194 my $self = shift;
195 my $adapt = $self->{adapt}->inherit($self); delete $adapt->{adapt};
196 return $self->adjustInherit($self->{adapt});
197}
198
199#
200# Inherit from the main FormulaUpToConstant, but
201# adjust the test points to include the constants
202#
203sub adjustInherit {
204 my $self = shift;
205 my $f = shift->inherit($self);
206 delete $f->{adapt}; delete $f->{constant};
207 foreach my $id ('test_points','test_at') {
208 if (defined $f->{$id}) {
209 $f->{$id} = [$f->{$id}->value] if Value::isValue($f->{$id});
210 $f->{$id} = [$f->{$id}] unless ref($f->{$id}) eq 'ARRAY';
211 $f->{$id} = [map {
212 (Value::isValue($_) ? [$_->value] :
213 (ref($_) eq 'ARRAY'? $_ : [$_]))
214 } @{$f->{$id}}];
215 $f->{$id} = $self->addConstants($f->{$id});
216 }
217 }
218 return $f;
219}
220
221#
222# Insert dummy values for the constants for the test points
223# (These are supposed to be +C, so the value shouldn't matter?)
224#
225sub addConstants {
226 my $self = shift; my $points = shift;
227 my @names = $self->context->variables->variables;
228 my $variables = $self->context->{variables};
229 my $Points = [];
230 foreach my $p (@{$points}) {
231 if (scalar(@{$p}) == scalar(@names)) {
232 push (@{$Points},$p);
233 } else {
234 my @P = (.1) x scalar(@names); my $j = 0;
235 foreach my $i (0..scalar(@names)-1) {
236 if (!$variables->{$names[$i]}{arbitraryConstant}) {
237 $P[$i] = $p->[$j] if defined $p->[$j]; $j++;
238 }
239 }
240 push (@{$Points}, \@P);
241 }
242 }
243 return $Points;
184} 244}
185 245
186################################################## 246##################################################
187# 247#
188# Here we override part of the answer comparison 248# Here we override part of the answer comparison
195# Show hints by default 255# Show hints by default
196# 256#
197sub cmp_defaults {((shift)->SUPER::cmp_defaults,showHints => 1, showLinearityHints => 1)}; 257sub cmp_defaults {((shift)->SUPER::cmp_defaults,showHints => 1, showLinearityHints => 1)};
198 258
199# 259#
260# Provide diagnostics based on the adapted function used to check
261# the student's answer
262#
263sub cmp_diagnostics {
264 my $self = shift;
265 $self->inherit($self->{adapt})->SUPER::cmp_diagnostics(@_);
266}
267
268#
269# Make it possible to graph single-variable formulas by setting
270# the arbitrary constants to 0 first.
271#
272sub cmp_graph {
273 my $self = shift; my $diagnostics = shift;
274 my $F1 = shift; my $F2; ($F1,$F2) = @{$F1} if (ref($F1) eq 'ARRAY');
275 my %subs; my $context = $self->context;
276 foreach my $v ($context->variables->variables)
277 {$subs{$v} = 0 if ($context->variables->get($v)->{arbitraryConstant})}
278 $F1 = $F1->inherit($F1->{adapt})->substitute(%subs)->reduce;
279 $F2 = $F2->inherit($F2->{adapt})->substitute(%subs)->reduce;
280 $self->SUPER::cmp_graph($diagnostics,[$F1,$F2]);
281}
282
283#
200# Add useful messages, if the author requested them 284# Add useful messages, if the author requested them
201# 285#
202sub cmp_postprocess { 286sub cmp_postprocess {
203 my $self = shift; my $ans = shift; 287 my $self = shift; my $ans = shift;
204 $self->SUPER::cmp_postprocess($ans); 288 $self->SUPER::cmp_postprocess($ans,@_);
205 return unless $ans->{score} == 0 && !$ans->{isPreview}; 289 return unless $ans->{score} == 0 && !$ans->{isPreview};
206 return if $ans->{ans_message} || !$self->getFlag("showHints"); 290 return if $ans->{ans_message} || !$self->getFlag("showHints");
207 my $student = $ans->{student_value}; 291 my $student = $ans->{student_value};
208 my $result = $ans->{correct_value} <=> $student; # compare encodes the reason in the result 292 $main::{_cmp_} = sub {return $ans->{correct_value} <=> $student}; # compare encodes the reason in the result
293 my $result = main::PG_restricted_eval('&{$main::{_cmp_}}');
294 delete $main::{_cmp_};
209 $self->cmp_Error($ans,"Note: there is always more than one posibility") if $result == 2 || $result == 3; 295 $self->cmp_Error($ans,"Note: there is always more than one posibility") if $result == 2 || $result == 3;
210 if ($result == 3) { 296 if ($result == 3) {
211 my $context = $self->context; 297 my $context = $self->context;
212 $context->flags->set(no_parameters=>0); 298 $context->flags->set(no_parameters=>0);
213 $context->variables->add(x00=>'Real'); 299 $context->variables->add(x00=>'Real');
214 $result = 1 if $self->removeConstant+"n01+n00x00" == $student+"x00"; # must use both parameters 300 my $correct = $self->removeConstant+"n01+n00x00"; # must use both parameters
301 $result = 1 if $correct->cmp_compare($student+"x00",{});
215 $context->variables->remove('x00'); 302 $context->variables->remove('x00');
216 $context->flags->set(no_parameters=>1); 303 $context->flags->set(no_parameters=>1);
217 } 304 }
218 $self->cmp_Error($ans,"Your answer is not the most general solution") if $result == 1; 305 $self->cmp_Error($ans,"Your answer is not the most general solution") if $result == 1;
219 $self->cmp_Error($ans,"Your formula should be linear in the constant '$student->{constant}'") 306 $self->cmp_Error($ans,"Your formula should be linear in the constant '$student->{constant}'")
229# 316#
230# Remove the constant and return a Formula object 317# Remove the constant and return a Formula object
231# 318#
232sub removeConstant { 319sub removeConstant {
233 my $self = shift; 320 my $self = shift;
234 main::Formula($self->substitute($self->{constant}=>0))->reduce; 321 return $self->adjustInherit(main::Formula($self->substitute($self->{constant}=>0))->reduce);
235} 322}
236 323
237# 324#
238# Override the differentiation so that we always return 325# Override the differentiation so that we always return
239# a Formula, not a FormulaUpToConstant (we don't want to 326# a Formula, not a FormulaUpToConstant (we don't want to

Legend:
Removed from v.5556  
changed lines
  Added in v.5917

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9