|
66 | 66 | Not[MemberQ[namedVariables, a]] := \!\(\* |
67 | 67 | TagBox[ |
68 | 68 | StyleBox[ |
| 69 | +RowBox[{"\n", " ", |
69 | 70 | RowBox[{"If", "[", |
70 | 71 | RowBox[{ |
71 | 72 | RowBox[{"OptionValue", "[", "Atomic", "]"}], ",", |
|
75 | 76 | RowBox[{ |
76 | 77 | RowBox[{"pattern", "[", |
77 | 78 | RowBox[{"a", ",", |
78 | | -RowBox[{"Blank", "[", "]"}]}], "]"}], ",", "AtomQ"}], "]"}], "]"}], ")"}], ",", |
| 79 | +RowBox[{"Blank", "[", "]"}]}], "]"}], ",", "AtomQ"}], "]"}], "]"}], ")"}], ",", "\n", " ", |
79 | 80 | RowBox[{"(", |
80 | 81 | RowBox[{"Optional", "[", |
81 | 82 | RowBox[{"pattern", "[", |
82 | 83 | RowBox[{"a", ",", |
83 | | -RowBox[{"Blank", "[", "]"}]}], "]"}], "]"}], ")"}]}], "]"}], |
| 84 | +RowBox[{"Blank", "[", "]"}]}], "]"}], "]"}], ")"}]}], "]"}]}], |
84 | 85 | ShowSpecialCharacters->False, |
85 | 86 | ShowStringCharacters->True, |
86 | 87 | NumberMarks->True], |
|
102 | 103 |
|
103 | 104 | DepatternizePattern[pattern_] := pattern |
104 | 105 |
|
105 | | -ComplexResolve[Optional[a_Symbol] + I Optional[b_Symbol]] := |
106 | | - Complex[a, b] |
107 | | - |
108 | | -ComplexResolve[I Optional[b_Symbol]*Pi] := Complex[0, b]*Pi |
109 | | - |
110 | | -ComplexResolve[Complex[0, Optional[b_Symbol]] + Optional[a_Symbol]] := |
111 | | - Complex[a, b] |
112 | | - |
113 | | -ComplexResolve[a_] := a |
114 | | - |
115 | 106 | Options[Patternize] = {Atomic -> False}; |
116 | 107 |
|
117 | 108 | Patternize[expression_, namedVariables_, OptionsPattern[]] := |
|
125 | 116 | has the same structure as a given answer template, given a set of \ |
126 | 117 | named variables.*) |
127 | 118 |
|
128 | | -inertFunctionRules = {Sin -> fSin,sin->fSin, Cos -> fCos,cos->fCos, Tan -> fTan, tan->fTan, |
129 | | - Sec -> fSec,sec->fSec, Csc -> fCsc,Cosec->fCsc,csc->fCsc,cosec->fCsc, Cot -> fCot, cot->fCot,ArcSin -> fArcSin, arcsin->fArcSin,asin->fArcSin, |
130 | | - ArcCos -> fArcCos,arccos->fArcCos,acos->fArcCos, ArcTan -> fArcTan,arctan->fArcTan,atan->fArcTan, ArcSec -> fArcSec, arcsec->fArcSec,asec->fArcSec, |
131 | | - ArcCsc -> fArcCsc,ArcCosec->fArcCsc,arccsc->fArcCsc,acsc->fArcCsc,acosec->fArcCsc, ArcCot -> fArcCot,arccot->fArcCot,acot->fArcCot, Sinh -> fSinh,sinh->fSinh, Cosh -> fCosh,cosh->fCosh,anh -> fTanh,tanh->fTanh, Sech -> fSech,sech->fSech, Csch -> fCsch,Cosech->fCsch,csch->fCsch,cosech->fCsch, Coth -> fCoth, coth->fCoth, |
132 | | - ArcSinh -> fArcSinh, arcsinh->fArcSinh,asinh->fArcSinh, ArcCosh -> fArcCosh,arccosh->fArcCosh,acosh->fArcCosh, ArcTanh -> fArcTanh,arctanh->fArcTanh,atanh->fArcTanh, |
133 | | - ArcSech -> fArcSech, arcsech->fArcSech,asech->fArcSech, ArcCsch -> fArcCsch,ArcCosech->fArcCsch,arccsch->fArcCsch,acsch->fArcCsch,acosech->fArcCsch, ArcCoth -> fArcCoth,arccoth->fArcCoth,acoth->fArcCoth, |
134 | | - Exp -> fExp,exp->fExp, Log -> fLog,log->fLog}; |
| 119 | +inertFunctionRules = { |
| 120 | + Sin -> fSin, sin -> fSin, Cos -> fCos,cos->fCos, Tan -> fTan, tan -> fTan, |
| 121 | + Sec -> fSec, sec -> fSec, Csc -> fCsc, Cosec -> fCsc, csc -> fCsc, cosec -> fCsc, Cot -> fCot, cot -> fCot, |
| 122 | + ArcSin -> fArcSin, arcsin -> fArcSin, asin -> fArcSin, ArcCos -> fArcCos, arccos -> fArcCos, acos -> fArcCos, |
| 123 | + ArcTan -> fArcTan, arctan -> fArcTan, atan -> fArcTan, |
| 124 | + ArcSec -> fArcSec, arcsec -> fArcSec, asec -> fArcSec, |
| 125 | + ArcCsc -> fArcCsc, ArcCosec -> fArcCsc, arccsc -> fArcCsc, acsc -> fArcCsc, acosec -> fArcCsc, |
| 126 | + ArcCot -> fArcCot, arccot -> fArcCot, acot -> fArcCot, |
| 127 | + Sinh -> fSinh, sinh -> fSinh, Cosh -> fCosh, cosh -> fCosh, tanh -> fTanh, tanh->fTanh, |
| 128 | + Sech -> fSech, sech -> fSech, Csch -> fCsch, Cosech -> fCsch, csch -> fCsch, cosech -> fCsch, Coth -> fCoth, coth->fCoth, |
| 129 | + ArcSinh -> fArcSinh, arcsinh -> fArcSinh, asinh -> fArcSinh, ArcCosh -> fArcCosh, arccosh -> fArcCosh, acosh -> fArcCosh, |
| 130 | + ArcTanh -> fArcTanh, arctanh -> fArcTanh, atanh -> fArcTanh, |
| 131 | + ArcSech -> fArcSech, arcsech -> fArcSech, asech -> fArcSech, |
| 132 | + ArcCsch -> fArcCsch, ArcCosech -> fArcCsch, arccsch -> fArcCsch, acsch -> fArcCsch, acosech -> fArcCsch, |
| 133 | + ArcCoth -> fArcCoth, arccoth -> fArcCoth, acoth->fArcCoth, |
| 134 | + Exp -> fExp, exp -> fExp, Log -> fLog, log -> fLog, ln -> fLog}; |
| 135 | + |
| 136 | +ComplexSymbolize[a_Integer?Positive]:=Symbol["$sym"<>ToString[a]] |
| 137 | + |
| 138 | +ComplexSymbolize[a_Integer?Negative]:=Symbol["$symmin"<>ToString[-a]] |
| 139 | + |
| 140 | +ComplexSymbolize[a_Rational] :=Symbol["$num"<>ToString[Numerator[a]]<>"den"<>ToString[Denominator[a]]] |
| 141 | + |
| 142 | +ComplexSymbolize[0]:=0 |
| 143 | + |
| 144 | +CanonicComplex[Complex[a_,b_]]:=ComplexSymbolize[a]+ComplexSymbolize[b] I |
| 145 | + |
| 146 | +CanonicComplex[I]:=I |
| 147 | + |
| 148 | +CanonicComplex[arg_]:=arg |
135 | 149 |
|
136 | 150 | Options[StructureMatchQ] = {Atomic -> False}; |
137 | 151 |
|
138 | | -StructureMatchQ[response_, answerTemplate_, namedVariables_, |
139 | | - OptionsPattern[]] := |
140 | | - Module[{response2, answerTemplate2}, |
141 | | - response2 = ReplaceAll[response, inertFunctionRules]; |
142 | | - answerTemplate2 = ReplaceAll[answerTemplate, inertFunctionRules]; |
143 | | - MatchQ[response2, |
144 | | - Patternize[answerTemplate2, namedVariables, |
145 | | - Atomic -> OptionValue[Atomic]]]] |
| 152 | +StructureMatchQ[response_,answerTemplate_,namedVariables_] := |
| 153 | + Module[{response2,answerTemplate2},response2=MapAll[CanonicComplex,ReplaceAll[response,inertFunctionRules]]; |
| 154 | + answerTemplate2=ReplaceAll[answerTemplate,inertFunctionRules]; |
| 155 | + MatchQ[response2,Patternize[answerTemplate2,namedVariables]]] |
146 | 156 |
|
147 | 157 | equalQStructure[answer_, response_, params_] := Module[{namedVariables,correctQ}, |
148 | 158 | Print["Evaluating Structure"]; |
|
158 | 168 | |> |
159 | 169 | ] |
160 | 170 |
|
| 171 | +(* SemanticAndStructureMatchQ: a function that checks whether a user's response both |
| 172 | + (a) is the same mathematical object as a given answer,and (b) has the same structure as a given answer template, |
| 173 | + given a set of named variables. *) |
| 174 | + |
| 175 | +activeFunctionRules = { |
| 176 | + sin -> Sin, cos -> Cos, tan -> Tan, sec -> Sec, Cosec -> Csc, csc -> Csc, cosec -> Csc, cot -> Cot, |
| 177 | + arcsin -> ArcSin, asin -> ArcSin, arccos -> ArcCos, acos -> ArcCos, arctan -> ArcTan, atan -> ArcTan, |
| 178 | + arcsec -> ArcSec, asec -> ArcSec, ArcCosec -> ArcCsc, arccsc -> ArcCsc, acsc -> ArcCsc, acosec -> ArcCsc, |
| 179 | + arccot -> ArcCot,acot -> ArcCot, |
| 180 | + sinh -> Sinh, cosh -> Cosh, tanh -> Tanh, sech -> Sech, Cosech -> Csch, csch -> Csch, cosech -> Csch, coth -> Coth, |
| 181 | + arcsinh -> ArcSinh, asinh -> ArcSinh, arccosh -> ArcCosh, acosh -> ArcCosh, arctanh -> ArcTanh, atanh -> ArcTanh, |
| 182 | + arcsech -> ArcSech, asech -> ArcSech, |
| 183 | + ArcCsch -> ArcCsch, ArcCosech -> ArcCsch, arccsch->ArcCsch, acsch -> ArcCsch, acosech -> ArcCsch, |
| 184 | + arccoth -> ArcCoth, acoth -> ArcCoth, |
| 185 | + exp -> Exp, log -> Log, ln -> Log}; |
| 186 | + |
| 187 | +SemanticMatchQ[response_,answer_] := Simplify[(response-answer)/.activeFunctionRules] == 0 |
| 188 | + |
| 189 | +SemanticAndStructureMatchQ[response_,answer_,answerTemplate_,namedVariables_] := |
| 190 | + TrueQ[SemanticMatchQ[response,answer]&&StructureMatchQ[response,answerTemplate,namedVariables]] |
| 191 | + |
| 192 | +equalQSemantic[answer_, response_, params_] := Module[{correctQ}, |
| 193 | + Print["Evaluating Semantic"]; |
| 194 | + correctQ = SemanticMatchQ[ |
| 195 | + ToExpression[ToString[response],TraditionalForm], |
| 196 | + ToExpression[ToString[answer],TraditionalForm]]; |
| 197 | + |
| 198 | + <| |
| 199 | + "error" -> Null, |
| 200 | + "is_correct" -> correctQ |
| 201 | + |> |
| 202 | +] |
| 203 | + |
| 204 | +equalQSemanticAndStructure[answer_, response_, params_] := Module[{namedVariables,answerTemplate,correctQ}, |
| 205 | + Print["Evaluating SemanticAndStructure"]; |
| 206 | + namedVariables = ToExpression[Lookup[params,"named_variables",{}],TraditionalForm]; |
| 207 | + answerTemplate = ToExpression[Lookup[params,"answer_template",{}],TraditionalForm]; |
| 208 | + correctQ = SemanticAndStructureMatchQ[ |
| 209 | + ToExpression[ToString[response],TraditionalForm], |
| 210 | + ToExpression[ToString[answer],TraditionalForm], |
| 211 | + ToExpression[ToString[answerTemplate],TraditionalForm], |
| 212 | + namedVariables |
| 213 | + ]; |
| 214 | + |
| 215 | + <| |
| 216 | + "error" -> Null, |
| 217 | + "is_correct" -> correctQ |
| 218 | + |> |
| 219 | +] |
| 220 | + |
161 | 221 | (* The evaluation function itself *) |
162 | 222 |
|
163 | 223 | evalQ[type_, answer_, response_, params_] := Module[{}, |
164 | 224 | Which[ |
165 | 225 | type == "structure", |
166 | 226 | equalQStructure[answer,response,params], |
| 227 | + type == "semantic", |
| 228 | + equalQSemantic[answer,response,params], |
| 229 | + type = "semantic_and_structure", |
| 230 | + equalQSemanticAndStructure[answer,response,params], |
167 | 231 | NumericQ[answer], |
168 | 232 | equalQNumeric[answer, response, params], |
169 | 233 | True, |
|
0 commit comments