Rev 17292 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
18203 | reyssat | 1 | !! this file is an annex for anstype litexp (or other) |
2 | !! some debugging information is stored in variable debuginfo, may be erased in a few months after 2024.05.01 |
||
3 | !! see documentation at end of file |
||
17282 | guerimand | 4 | |
18203 | reyssat | 5 | debuginfo=Analyse de $wims_read_parm |
6 | !if factorcontent notwordof $(replyoption$i) |
||
7 | debuginfo=$debuginfo sans factorcontent |
||
8 | !else |
||
9 | debuginfo=$debuginfo avec factorcontent |
||
10 | !endif |
||
11 | allowedchar=!text mark (,),*,^,-,+,0,1,2,3,4,5,6,7,8,9,a,b,c,d,f,g,h,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,F,G,H,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z in $wims_read_parm |
||
12 | !! due to rawmath, only x,y,z are accepted letters |
||
13 | !!allowedchar=!text mark (,),*,^,-,+,0,1,2,3,4,5,6,7,8,9,x,y,z,X,Y,Z in $wims_read_parm |
||
14 | badpositions=!positionof char 0 in $allowedchar |
||
15 | !if $badpositions!=$empty |
||
16 | badposition=!item 1 of $badpositions |
||
17 | badchar=!char $badposition of $wims_read_parm |
||
18 | wrong=badform usebadchar $badchar |
||
19 | !endif |
||
20 | debuginfo=$debuginfo $wrong |
||
17282 | guerimand | 21 | pg=!char 1 of () |
22 | pd=!char 2 of () |
||
18203 | reyssat | 23 | !!********** wims_read_parm is rawmath-formated user's answer |
17282 | guerimand | 24 | nb=!charcnt $wims_read_parm |
25 | !distribute item 0,1,0 into par,flag,par2 |
||
18203 | reyssat | 26 | !reset factor lfactors exp content lcontent flagpard |
27 | operand=!exec maxima op($wims_read_parm) |
||
28 | wrp=!replace - by +2* in $wims_read_parm |
||
29 | !!********** partly avoid maxima's evaluation before op (^^ not simplified) |
||
30 | wrp=!replace internal * by ^^ in $wrp |
||
31 | operand=!exec maxima op($wrp) |
||
32 | operand=!replace internal ^^ by * in $operand |
||
33 | debuginfo=$debuginfo operande=$operand |
||
17282 | guerimand | 34 | k=1 |
18203 | reyssat | 35 | !!********** read string until end or error |
36 | !while ($k<=$nb and $wrong=$empty) or $factor!=$empty |
||
17292 | guerimand | 37 | c=!char $k of $wims_read_parm |
18203 | reyssat | 38 | cc=!char $[$k+1] of $wims_read_parm |
39 | debuginfo=$debuginfo\ |
||
40 | $c |
||
41 | !!********* condition to decide that the end of the factor is attained |
||
42 | !if $k>$nb or ($c=* and $par=0 and ($pg isin $wims_read_parm or $operand!="+")) |
||
43 | debuginfo=$debuginfo factor=$factor, exp=$exp |
||
17292 | guerimand | 44 | !if $factor!=$empty |
45 | !if $mpar2>0 |
||
46 | wrong=badform fparenthesis $factor |
||
47 | !break |
||
48 | !else |
||
18203 | reyssat | 49 | !!********* test to decide if factor contains a variable (NaN), then factorize it via pari (gets only polynomial factors, not the content, ex : 2x^2-2 --> factor= x+1,1 ; x-1,1 ) |
17292 | guerimand | 50 | !if $[$factor*1]=NaN |
18203 | reyssat | 51 | debuginfo=$debuginfo il contient une variable, |
52 | !!********* The old line about content is now useless because we test below that factor is irreducible (hence without content) |
||
53 | !!********* if factor is a power, remove the power (use maxima op, hence first remove - sign, replace temporarily by unused letter e) |
||
54 | Nfactor=!replace - by +e in $factor |
||
55 | foperand=!exec maxima op($Nfactor) |
||
56 | !if $foperand="^" |
||
57 | factor=!exec maxima part($Nfactor,1) |
||
58 | factor=!replace +e by - in $factor |
||
59 | factor=!replace e by - in $factor |
||
60 | exp=!exec maxima part($Nfactor,2) |
||
61 | exp=!replace +e by - in $exp |
||
62 | exp=!replace e by - in $exp |
||
63 | debuginfo=$debuginfo (factor=$factor, exp=$exp) |
||
64 | !endif |
||
65 | t1=!exec pari factor($factor) |
||
66 | debuginfo=$debuginfo pari donne la factorisation $t1 |
||
67 | !!********* The old line "!replace internal -1,1; by $empty" is removed, because useless (since pari gives only non constant factors, hence never (-1)^1), and even inappropriate if factorization is x-1,1. |
||
17292 | guerimand | 68 | tt1=!rowcnt $t1 |
18203 | reyssat | 69 | !!********* Check that current factor is irreducible (equal up to sign to unique factor of its pari-factorization). Content check is useless. |
70 | prime=!item 1 of $t1 |
||
71 | exp=!item 2 of $t1 |
||
72 | isirred=!exec maxima expand((($prime)-($factor))*(($prime)+$factor)) |
||
73 | debuginfo=$debuginfo $factor prime=$prime isirred=$isirred |
||
74 | !if $tt1!=1 or $isirred!=0 |
||
17292 | guerimand | 75 | wrong=badform notcomplete $factor |
18203 | reyssat | 76 | debuginfo=$debuginfo notcomplete |
77 | !else |
||
78 | !!********* If current factor not correctly expanded, this is reported in variable wrong by file expandpolynome. |
||
17292 | guerimand | 79 | !read oef/analyse/expandpolynome $factor |
18203 | reyssat | 80 | debuginfo=$debuginfo on teste via expandpolynome |
17292 | guerimand | 81 | !endif |
18203 | reyssat | 82 | !!********* send error if current factor is already in list, add it otherwise |
83 | !if $prime isitemof $lfactors |
||
84 | wrong=badform multifactor $prime |
||
17292 | guerimand | 85 | !else |
18203 | reyssat | 86 | lfactors=!append item $prime to $lfactors |
17292 | guerimand | 87 | !endif |
17282 | guerimand | 88 | !else |
18203 | reyssat | 89 | debuginfo=$debuginfo il est numérique |
17292 | guerimand | 90 | !if factorcontent notwordof $(replyoption$i) |
18203 | reyssat | 91 | !!********* When no option factorcontent, check that the current numerical factor is the first one (only one is allowed), and not equal to 1 |
17292 | guerimand | 92 | !if $content!=$empty |
93 | wrong=badform twofactorcst $content $factor |
||
17282 | guerimand | 94 | !endif |
18203 | reyssat | 95 | !default exp=1 |
96 | !if $[($factor)^$exp]=1 and $[$$wims_read_parm]!=1 |
||
97 | wrong=badform uselessfactor |
||
98 | !break |
||
99 | !endif |
||
17292 | guerimand | 100 | content=$factor |
17282 | guerimand | 101 | !else |
18203 | reyssat | 102 | !!********* When option factorcontent, we check that the current numerical factor has only one prime factor (apart sign) |
17292 | guerimand | 103 | tmp=!exec pari factor($factor) |
104 | tmp=!replace internal -1,1; by $empty in $tmp |
||
105 | tt1=!rowcnt $tmp |
||
106 | !if $tt1!=1 |
||
107 | wrong=badform factorcontent $factor |
||
18203 | reyssat | 108 | !else |
109 | !default exp=1 |
||
110 | debuginfo=$debuginfo factor^exp= $factor^$exp=$[($factor)^$exp] |
||
111 | !if $[($factor)^$exp]=1 and $[$$wims_read_parm]!=1 |
||
112 | wrong=badform uselessfactor |
||
113 | !break |
||
114 | !endif |
||
115 | premier=!item 1 of $tmp |
||
116 | !if $premier=matrix(0,2) |
||
117 | premier=1 |
||
118 | !endif |
||
119 | premierf=!replace \^.* by in $factor |
||
120 | !if ($premier!=$premierf) and (-$premier!=$premierf) |
||
121 | debuginfo=$debuginfo premier=$premier, premierf=$premierf |
||
122 | wrong=badform factorcontent $factor |
||
123 | !endif |
||
124 | !if $premier isitemof $lcontent |
||
125 | wrong=badform multifactor $premier |
||
126 | !else |
||
127 | lcontent=!append item $premier to $lcontent |
||
128 | !endif |
||
129 | debuginfo=$debuginfo tmp=$tmp lcontent=$lcontent |
||
17282 | guerimand | 130 | !endif |
131 | !endif |
||
132 | !endif |
||
18203 | reyssat | 133 | !reset factor exp flagpard |
17292 | guerimand | 134 | mpar2=0 |
17282 | guerimand | 135 | !endif |
17292 | guerimand | 136 | !endif |
137 | flag=1 |
||
138 | !else |
||
18203 | reyssat | 139 | debuginfo=$debuginfo factor=$factor exp=$exp par=$par par2=$par2 mpar2=$mpar2 wrong=$wrong c=$c |
140 | !!********** condition on pg because x-1 or 2x-1 alone is a correct factorization. |
||
141 | !if $c isin +- and $par=0 and $factor!=$empty and $pg isin $wims_read_parm |
||
142 | debuginfo=$debuginfo notfactorised $k |
||
17292 | guerimand | 143 | wrong=badform notfactorised $k |
18203 | reyssat | 144 | factor= |
17282 | guerimand | 145 | !else |
18203 | reyssat | 146 | !if $c notin () |
147 | !if $c=^ |
||
148 | exp=0 |
||
149 | flagexp=1 |
||
150 | !if $flagpard=$empty |
||
151 | factor=$factor$c |
||
152 | !endif |
||
153 | !else |
||
154 | !if $exp=$empty |
||
155 | debuginfo=$debuginfo ajout de $c |
||
156 | factor=$factor$c |
||
17282 | guerimand | 157 | !else |
18203 | reyssat | 158 | !if ($c isin 0123456789) |
159 | !if ($flagexp=1) |
||
160 | exp=$exp$c |
||
161 | !endif |
||
162 | !else |
||
163 | flagexp=0 |
||
164 | !endif |
||
165 | !!********** we continue the construction of current factor |
||
166 | !if $flagpard=$empty or $operand="+" |
||
167 | debuginfo=$debuginfo encore ajout de $c |
||
17282 | guerimand | 168 | factor=$factor$c |
169 | !endif |
||
170 | !endif |
||
18203 | reyssat | 171 | !endif |
172 | !else |
||
173 | !if $c=$pg |
||
174 | !if $flag=0 or $par>0 |
||
175 | !increase par2 |
||
176 | mpar2=$par2 |
||
177 | !endif |
||
178 | !if (($par>0 or $par2>0) and $exp=$empty) or $operand="+" |
||
179 | debuginfo=$debuginfo on ajoute $c |
||
180 | factor=$factor$c |
||
181 | !endif |
||
182 | !increase par |
||
183 | flag=1 |
||
17282 | guerimand | 184 | !else |
18203 | reyssat | 185 | debuginfo=$debuginfo pardroite |
186 | flagpard=1 |
||
187 | !if $mpar2>0 |
||
188 | mpar2=$[$mpar2-1] |
||
189 | par2=$[$par2-1] |
||
190 | !endif |
||
191 | par=$[$par-1] |
||
192 | !if (($par>0 or $par2>0) and $exp=$empty) or $operand="+" |
||
193 | factor=$factor$c |
||
17282 | guerimand | 194 | !endif |
18203 | reyssat | 195 | debuginfo=$debuginfo envoi pour test de $factor |
196 | !if $par2>0 |
||
197 | par2=$[$par2-1] |
||
198 | !endif |
||
199 | flag=0 |
||
17282 | guerimand | 200 | !endif |
201 | !endif |
||
202 | !endif |
||
17292 | guerimand | 203 | !endif |
204 | !increase k |
||
18203 | reyssat | 205 | debuginfo=$debuginfo\ |
206 | endwhile $c $k/$nb, wrong=$wrong, factor=$factor |
||
17282 | guerimand | 207 | !endwhile |
18203 | reyssat | 208 | |
209 | !exit |
||
210 | |||
211 | |||
212 | !if $wrong!=$empty |
||
213 | !!debug $debuginfo\ |
||
214 | sortie avec wrong=$wrong |
||
215 | !endif |
||
216 | |||
217 | |||
218 | |||
219 | Nothing is read by wims after this point, it is just here for information |
||
220 | To debug this file, put the !exit command 5 lines below. |
||
221 | |||
222 | Documentation |
||
223 | ------------- |
||
224 | |||
225 | This file checks whether wims_read_parm is a factorized polynomial of Z[X] (or any variable except e,E,i,I), |
||
226 | each factor being simplified as described in file expandpolynome of this directory. |
||
227 | It assumes that wims_read_parm has been formated by the rawmath function (as is done in the file litexp), |
||
228 | so is presented with * between factors and without spaces. |
||
229 | |||
230 | errors checked (for factor): |
||
231 | - notcomplete : a factor is not completely factorised |
||
232 | - multifactor : a factor is repeated instead of using power |
||
233 | - twofactorcst : the constant factor is not unique (when no option factorcontent) |
||
234 | - factorcontent : content of the polynome is not factorized (when option factorcontent) |
||
235 | - notfactorised : expression is not a product |
||
236 | - usebadchar : forbidden characters used in polynomial (like /.eEiI) the letters e,E,i,I have a numerical value when wims calls pari |
||
237 | - uselessfactor : factor has value 1 (not always checked) |
||
238 | - fparenthesis : factor contains a parenthesis |
||
239 | |||
240 | some variables : |
||
241 | par is number of not yet closed left parenthesis when scanning the expression |
||
242 | mpar2 is maximal number of parentheses attained in the factor (should be 0 if simplified) |
||
243 | lfactors is current list of non constant irreducible factors |
||
244 | content is empty until some constant factor is found (used when no option factorcontent) |
||
245 | lcontent is current list of constant prime factors (used when option factorcontent) |
||
246 | exp is the exponent (number following ^) |
||
247 | flagpard used to decide whether exp is part of factor itself. |
||
248 | allowedchar is the list of allowed characters in the expression. |
||
249 | e,E,i,I should be forbidden because they have numerical value in pari factorization. |
||
250 | Letters other than x,y,z are considered as function names by rawmath when in front of a left parenthesis. Hence x(x+1) and (u-1)(u+1) are ok as polynomials, but not u(u+1). |
||
251 | Since some exercises (H2/algebra/OEFevalwimslitt.fr) already use letter b, all letters except e,i are allowed, but the documentation should mention this behavior : |
||
252 | it is not safe to use letters other than x,y,z in the good answer if it is not given in machine-understandable format. |
||
253 | We could change this behavior via a new option (strictvar, to limit variable names to x,y,z). |
||
254 | Users might be tempted t use / or . because they are common (ex : 15.0/3*x^2) but fthey are forbidden because too difficult to treat in this file. |
||
255 | |||
256 | How does it work? |
||
257 | - We first check there are only allowed characters in the expression |
||
258 | - Then we read the string character by character, to find the factors. Because the input comes from rawmath, the factors are separated by a *. |
||
259 | Hence the general idea is that a factor ends when it is followed by a *, except if we are inside a pair of parentheses : 2 is a factor in 2*(x+1) but not in 3*(2*x+1) |
||
260 | But this is not always correct : 2 is not a factor in 2*x+1 or 2*(x+1)*(x+2)-1. In general it is not possible to be sure that a factor ends before we read the entire expression (and write it as a tree). |
||
261 | This is why we use the maxima "op" operator (which does the tree job), to know if the entire expression is a sum or a product. If it is a sum, the only factor is the entire expression. |
||
262 | We have to cheat to use op because maxima evaluate op's argument : (-1)*(x-1) is a sum. |
||
263 | If it is a product, we apply the general idea above. |
||
264 | - Once we have found a factor, we treat separately the cases of a nonconstant or constant factor : |
||
265 | - for nonconstant factor (NaN), check that it is irreducible (equal up to sign to unique factor of its pari-factorization), correctly expanded (using file expandpolynome) and new (not in lfactors). |
||
266 | - for constant factor, separate in 2 cases depending on option factorcontent : |
||
267 | - without option factorcontent check that it is new and not of value 1. |
||
268 | - with option factorcontent check that it is primary, power of a new prime, and not of value 1. |
||
269 | - As soon as some error is found, it is stored in the variable wrong and we exit |
||
270 | |||
271 | |||
272 | |||
273 | |||
274 | To check this file, try the following exercise, with 6*(x-1)*(x+1) replaced by any other polynomial in machine understandable format. |
||
275 | You may try natural format (like 6(x-1)(x+1)) for user's answer |
||
276 | |||
277 | \text{P=6*(x-1)*(x+1)} |
||
278 | \statement{Factorize P=\P} |
||
279 | \answer{without option factorcontent }{\P}{type= litexp}{option=polfactor} |
||
280 | \answer{with option factorcontent}{\P}{type= litexp}{option=polfactor,factorcontent} |
||
281 | |||
282 | |||
283 | We comment here some examples for P, depending on option factorcontent (yes,no,any) |
||
284 | |||
285 | |||
286 | Correctly accepted : |
||
287 | |||
288 | P factorcontent remarks |
||
289 | 1 any |
||
290 | -2 any |
||
291 | -x any |
||
292 | -2x any |
||
293 | 8x no |
||
294 | 2^3x yes |
||
295 | -8x no |
||
296 | -2^3x yes |
||
297 | x^3 any |
||
298 | -x^3 any |
||
299 | x^(3) any |
||
300 | 2(x-1) any |
||
301 | (x-1)2 any |
||
302 | (x-1)^2 any |
||
303 | -(x-1)^2 any |
||
304 | x^2+1 any bug in original : blocked |
||
305 | x^2+x+1 any bug in original : blocked |
||
306 | 2x(1-x)(x+1) any |
||
307 | y(y+1) any |
||
308 | a-1 any bug in original : blocked |
||
309 | -1(1-a) any |
||
310 | -(1-a) any |
||
311 | -(x-1) any |
||
312 | |||
313 | |||
314 | |||
315 | Correctly blocked : |
||
316 | |||
317 | P factorcontent reason remarks |
||
318 | 4-2 yes factorcontent 4-2 |
||
319 | 8x yes factorcontent 8 bug in original : accepted |
||
320 | 2*2*2*x no twofactorcst 2 2 |
||
321 | 2*2*2*x yes multifactor 2 bug in original : accepted |
||
322 | -2*2 no twofactorcst -2 2 |
||
323 | -2*2 yes multifactor 2 bug in original : accepted |
||
324 | 2^3 2^2x no twofactorcst 2^3 2^2 |
||
325 | 2^3 2^2x yes multifactor 2 bug in original : accepted |
||
326 | (-1)(x-1)(x+1)(-1) no twofactorcst -1 -1 |
||
327 | (-1)(x-1)(x+1)(-1) yes multifactor -1 bug in original : accepted |
||
328 | (-1)(x-1)(x+1)((-1)) no twofactorcst -1 (-1) |
||
329 | (-1)(x-1)(x+1)((-1)) yes multifactor -1 |
||
330 | (x^2-1) any notcomplete (x^2-1) bug in original : accepted |
||
331 | x^2-1, -2x(x^2-1) any notcomplete x^2-1 bug in original : bad reasons |
||
332 | 2.0*x any usebadchar . different reason in original (accepted if no) |
||
333 | 2?0*x any usebadchar ? exercise error in original |
||
334 | 2/1*x any usebadchar / usedivide in original |
||
335 | 2*x-1*1 any notreduced termenumsimp -1*1 |
||
336 | 2x(1-x)2(x+1) no twofactorcst 2 2 |
||
337 | 2x(1-x)2(x+1) yes multifactor 2 bug in original : accepted |
||
338 | 2x(1-x)1(x+1) any uselessfactor |
||
339 | (-1)^2(x-1)(x+1) any uselessfactor accepted in original |
||
340 | 2*x*3^0 any uselessfactor |
||
341 | x^2+2x+1 any notcomplete x^2+2*x+1 bad reason in original |
||
342 | x(x^2+2x+1) any notcomplete x^2+2*x+1 bad reason in original |
||
343 | 2(x+1)-1 any notfactorised 8 |
||
344 | (x+1)x(x+1) any multifactor x+1 |
||
345 | (x+1)(-1-x) any multifactor x+1 |
||
346 | -2(1-x)(x^2+x+1-x^2)x any notreduced termesamepower x^2,-x^2 bad reason in original |
||
347 | (x+1)^3*(x+1)^(-1) any multifactor x+1 different reason in original |
||
348 | -14y(-11y+15)+2y(-11y+15) no notfactorised 17 |
||
349 | 6x(x-1)+1 no notfactorised 10 |
||
350 | 6x(x-1)+1 yes factorcontent 6 |
||
351 | 2*(1+(x+1)) any notreduced parenthesis |
||
352 | |||
353 | |||
354 | Correctly blocked, but for bad reason (bug) : |
||
355 | P factorcontent reason remarks |
||
356 | (x-1)*1 any notreduced parenthesis |
||
357 | x^(2x+1) any notcomplete x^2*x+1 P is not a polynomial, factor is wrong |
||
358 | x^2*x+1 any notcomplete x^2*x+1 bad reason in original |
||
359 | 3^(2+1) yes factorcontent 3^2+1 factor is wrong. Accepted in original |
||
360 | -14y(-11y+15)+2y(-11y+15) yes factorcontent -14 |
||
361 | |||
362 | |||
363 | |||
364 | Wrongly accepted (bug): |
||
365 | |||
366 | P factorcontent |
||
367 | |||
368 | |||
369 | Wrongly blocked (bug): |
||
370 | |||
371 | P factorcontent reason remarks |
||
372 | |||
373 | |||
374 | |||
375 | Accepted, but not sure it is what we want |
||
376 | |||
377 | P factorcontent remarks |
||
378 | 2^3x no the constant factor is not computed, but still accepted. |
||
379 | (-1)^3x any correct but not simplest form |
||
380 | 3^(2+1) no constant not completely computed |
||
381 | 4-2 no constant not completely computed. Blocked in original |
||
382 | 2^(1+0) any |
||
383 | 3^(7+7)x no clearly not simplest form |
||
384 | (2) any compare with (x+1) which is blocked |
||
385 | (x) any compare with (x+1) which is blocked |
||
386 | b^(3-3)*(a-1) any the letter b is not in the good answer. |
||
387 | (b-1)^(3-3)*(a-1) any blocked in original |
||
388 | |||
389 | |||
390 | Blocked, but not sure it is what we want |
||
391 | |||
392 | P factorcontent reason remarks |
||
393 | (x+1) any notreduced parenthesis accepted in original (better?) |
||
394 | |||
395 | |||
396 | |||
397 | Yet to be tested |
||
398 | P factorcontent reason remarks |
||
399 | |||
400 | |||
401 | known bugs : |
||
402 |