最大值匹配商函数
Matching quotient function in maxima
我们有一个在线平台,我们在后端使用 maxima 来反馈学生给出的答案。
假设多项式长除法的解是以下函数:
sol: 3+(2+4*x)/(3*x^2+2*x+8);
假设学生给出了答案:
ans: 3 +(3-5*x)/(3x^2+2*x+8)
然后我们想按照这些思路提供反馈。
Your answer is indeed of the following form:
The constant s is correct, but you didn't choose the right linear function r(x).
我尝试通过以下方式实现此反馈:
ans: 3 +(3-5*x)/(3x^2+2*x+8);
remvalue(a,b,c,d);
matchdeclare([a,b,c,d], constantp);
defmatch(match, d+ (a*x+b)/(3*x^2+2*x+8));
match(ans);
不过defmatch好像不能匹配这个。还有其他函数可以用来匹配这样的商函数吗?
它确实适用于更简单的场景:
ans: (3-5*x)/(3*x^2+2*x+8);
remvalue(a,b,c);
matchdeclare([a,b,c], constantp);
defmatch(match, (a*x+b)/(3*x^2+2*x+8));
match(ans);
如果题目都是多项式除法,或许可以用divide
函数求returns商和余数,然后验证学生的输入是否和商+[=39一样=].
至于匹配商 + remainder/divisor,defmatch
可能不够强大,因为它主要(虽然不完全)寻找正式匹配,而且在很多情况下它不能,检测等效但形式不同的表达式。
让我想想这个问题如何实现一个匹配函数。也许其他人也有建议。
编辑:这是一种匹配此类表达式的方法。我会将多项式的比率与其他项分开。如果只有一个比率项,其他项都是多项式,那么你想要的模式就匹配了。
我至少使用了一个晦涩但有用甚至易于理解的匹配 "+"
表达式的功能。由于 "+"
是可交换的,模式匹配器会扫除与尝试的第一个谓词匹配的所有参数,然后用第二个谓词扫过,如果有两个以上的预测。如果任何模式匹配变量被声明为匹配 all
,它匹配所有参数并且还剩下 none。将以相反的顺序尝试模式变量,因此 aa
将最后处理。效果是将 "+"
表达式划分为与规定谓词匹配的术语和其他所有内容的包罗万象。这在 %i7
.
中使用
(%i2) matchdeclare (pp, lambda ([e], polynomialp (e, [pvar]))) $
(%i3) matchdeclare (qq, lambda ([e], diff (e, pvar) # 0 and polynomialp (e, [pvar]))) $
(%i4) defmatch (match_pratio, pp/qq, pvar) $
(%i5) matchdeclare (aa, all) $
(%i6) matchdeclare (rr, lambda ([e], match_pratio (e, pvar) # false)) $
(%i7) defmatch (match_pratio_plus_remainder, rr + aa, pvar) $
(%i8) match_foo (e, pvar) :=
block ([aa, pp, qq, rr],
if match_pratio (e, pvar) # false
then [0, pp, qq, pp/qq]
elseif match_pratio_plus_remainder (e, pvar) # false
then if polynomialp (aa, [pvar]) and op(rr) # "+"
then [aa, pp, qq, rr]) $
以下是一些匹配的示例:
(%i9) match_foo (u^2/2 - 3*u + 1 + (u - 1)/(u^2 + u - 1), u);
2
u 2 u - 1
(%o9) [-- - 3 u + 1, u - 1, u + u - 1, ----------]
2 2
u + u - 1
(%i10) match_foo (u^2/2 - 3*u + 1 - 2*(u - 1)/(u^2 + u - 1), u);
2
u 2 2 (u - 1)
(%o10) [-- - 3 u + 1, - 2 (u - 1), u + u - 1, - ----------]
2 2
u + u - 1
(%i11) match_foo (u^2/2 - 3*u + 1 - 2/(u^2 + u - 1), u);
2
u 2 2
(%o11) [-- - 3 u + 1, - 2, u + u - 1, - ----------]
2 2
u + u - 1
(%i12) match_foo (1 - 2/(u^2 + u - 1), u);
2 2
(%o12) [1, - 2, u + u - 1, - ----------]
2
u + u - 1
(%i13) match_foo (- 2/(u^2 + u - 1), u);
2 2
(%o13) [0, - 2, u + u - 1, - ----------]
2
u + u - 1
以下是一些不匹配的示例:两个多项式比率项、没有多项式比率项和一个非多项式项。
(%i14) match_foo (1/u - 2/(u^2 + u - 1), u);
(%o14) false
(%i15) match_foo (1 - (u^2 + u - 1)/2, u);
(%o15) false
(%i16) match_foo (sin(u) - 2/(u^2 + u - 1), u);
(%o16) false
第二次编辑:我想我把 match_pratio_plus_remainder
命名错了,应该是 match_remainder_plus_quotient
。好吧。
我们有一个在线平台,我们在后端使用 maxima 来反馈学生给出的答案。
假设多项式长除法的解是以下函数:
sol: 3+(2+4*x)/(3*x^2+2*x+8);
假设学生给出了答案:
ans: 3 +(3-5*x)/(3x^2+2*x+8)
然后我们想按照这些思路提供反馈。
Your answer is indeed of the following form:
The constant s is correct, but you didn't choose the right linear function r(x).
我尝试通过以下方式实现此反馈:
ans: 3 +(3-5*x)/(3x^2+2*x+8);
remvalue(a,b,c,d);
matchdeclare([a,b,c,d], constantp);
defmatch(match, d+ (a*x+b)/(3*x^2+2*x+8));
match(ans);
不过defmatch好像不能匹配这个。还有其他函数可以用来匹配这样的商函数吗?
它确实适用于更简单的场景:
ans: (3-5*x)/(3*x^2+2*x+8);
remvalue(a,b,c);
matchdeclare([a,b,c], constantp);
defmatch(match, (a*x+b)/(3*x^2+2*x+8));
match(ans);
如果题目都是多项式除法,或许可以用divide
函数求returns商和余数,然后验证学生的输入是否和商+[=39一样=].
至于匹配商 + remainder/divisor,defmatch
可能不够强大,因为它主要(虽然不完全)寻找正式匹配,而且在很多情况下它不能,检测等效但形式不同的表达式。
让我想想这个问题如何实现一个匹配函数。也许其他人也有建议。
编辑:这是一种匹配此类表达式的方法。我会将多项式的比率与其他项分开。如果只有一个比率项,其他项都是多项式,那么你想要的模式就匹配了。
我至少使用了一个晦涩但有用甚至易于理解的匹配 "+"
表达式的功能。由于 "+"
是可交换的,模式匹配器会扫除与尝试的第一个谓词匹配的所有参数,然后用第二个谓词扫过,如果有两个以上的预测。如果任何模式匹配变量被声明为匹配 all
,它匹配所有参数并且还剩下 none。将以相反的顺序尝试模式变量,因此 aa
将最后处理。效果是将 "+"
表达式划分为与规定谓词匹配的术语和其他所有内容的包罗万象。这在 %i7
.
(%i2) matchdeclare (pp, lambda ([e], polynomialp (e, [pvar]))) $
(%i3) matchdeclare (qq, lambda ([e], diff (e, pvar) # 0 and polynomialp (e, [pvar]))) $
(%i4) defmatch (match_pratio, pp/qq, pvar) $
(%i5) matchdeclare (aa, all) $
(%i6) matchdeclare (rr, lambda ([e], match_pratio (e, pvar) # false)) $
(%i7) defmatch (match_pratio_plus_remainder, rr + aa, pvar) $
(%i8) match_foo (e, pvar) :=
block ([aa, pp, qq, rr],
if match_pratio (e, pvar) # false
then [0, pp, qq, pp/qq]
elseif match_pratio_plus_remainder (e, pvar) # false
then if polynomialp (aa, [pvar]) and op(rr) # "+"
then [aa, pp, qq, rr]) $
以下是一些匹配的示例:
(%i9) match_foo (u^2/2 - 3*u + 1 + (u - 1)/(u^2 + u - 1), u);
2
u 2 u - 1
(%o9) [-- - 3 u + 1, u - 1, u + u - 1, ----------]
2 2
u + u - 1
(%i10) match_foo (u^2/2 - 3*u + 1 - 2*(u - 1)/(u^2 + u - 1), u);
2
u 2 2 (u - 1)
(%o10) [-- - 3 u + 1, - 2 (u - 1), u + u - 1, - ----------]
2 2
u + u - 1
(%i11) match_foo (u^2/2 - 3*u + 1 - 2/(u^2 + u - 1), u);
2
u 2 2
(%o11) [-- - 3 u + 1, - 2, u + u - 1, - ----------]
2 2
u + u - 1
(%i12) match_foo (1 - 2/(u^2 + u - 1), u);
2 2
(%o12) [1, - 2, u + u - 1, - ----------]
2
u + u - 1
(%i13) match_foo (- 2/(u^2 + u - 1), u);
2 2
(%o13) [0, - 2, u + u - 1, - ----------]
2
u + u - 1
以下是一些不匹配的示例:两个多项式比率项、没有多项式比率项和一个非多项式项。
(%i14) match_foo (1/u - 2/(u^2 + u - 1), u);
(%o14) false
(%i15) match_foo (1 - (u^2 + u - 1)/2, u);
(%o15) false
(%i16) match_foo (sin(u) - 2/(u^2 + u - 1), u);
(%o16) false
第二次编辑:我想我把 match_pratio_plus_remainder
命名错了,应该是 match_remainder_plus_quotient
。好吧。