maths / moodle-qtype_stack

Stack question type for Moodle
GNU General Public License v3.0
141 stars 150 forks source link

Variables with ^ #1064

Closed JB74 closed 2 months ago

JB74 commented 10 months ago

Would it be possible to enable variables in STACK with ^
We use e.g. û heavily in electrical engineering for complex "pointers".

Best regards, Juergen

aharjula commented 10 months ago

Actually, we already support variables inside the question logic with any unicode "letters" as long as the Maxima underneath is new enough and properly configured.

The actual limiting factor here is with the student inputs having extra rules blocking more complicated characters from being used to avoid some confusion, for those inputting things and not noticing "extra accents", and yes those rules are silly in the modern world. These limits date back nearly 15 years when we had a nice little bug where inputting non-ASCII chars made the system break down and vomit out a bit too much information for the student to see, now we should be safe from that.

The bigger problem is that if we allow all chars, we might end up with a problem with certain characters looking the same but not being the same, for this we actually have a new feature from last summer that deals with this very issue on a small scale for parenthesis and some other special symbols. For example, there are Latin alphabet characters that look very much the same as some Cyrillic ones, and we might want to avoid collisions with them. So while the allowed set should probably be larger than ASCII it might still need to be somewhat limited as otherwise, our character replacement map could grow to be quite large.

Personally, I see no big problems opening up from ASCII letters to LATIN-1 letters at least with those letters, the developers can understand them, but at some point, someone will want us to support even more, and we need to think through how we do that and how we can target subsets of the whole possible world of characters in a somewhat consistent manner. If we allow ^ accented ones then what do we do with all the other accents, many of which can be easy to confuse (à vs. á etc.) with each other?

aharjula commented 10 months ago

To further complicate this issue, we really need to consider some of the accents that are possibly confused with operators. Basically, if someone enters "ū" do we consider that macron as an overline and if so will we then force some specific interpretation for it? Forcing an interpretation would probably be a bad thing, but if we do not then we need to ask if the student meant something specific if we see that and it is not a variable within the question itself.

The problem here is, that if we connect the logic for deciding which chars are acceptable to the chars used in the question itself, our character mapping logic becomes somewhat more complex we just cannot bulk replace things like we now do.

JB74 commented 10 months ago

I would suggest to stick to the "english" alphabet (in terms of "base" letters) and do not include any "accents" coming from other languages, as the main focus (at least from my side) are mathematical expressions. The "^" would reflect a peak value in electrical engineering. We could also use some commands (\hat{a}) as used in LaTeX, but this makes the live of the students more complicated, when entering results. But basically the same situations occurs for subscripts. I also would not do a special interpretation of e.g. û - as there is also no special interpretation of u_1 - which would be from my side basically two different variable names.

I am not that much involved in programming, so I cannot comment on this, but I come more from "the user" side as we would like to use STACK for our EE courses.

sangwinc commented 10 months ago

Anther option, which might work in some situations, is to use texput to tune the display. That's not what you need for student input but it will help teachers.

sangwinc commented 3 months ago

I'm picking up this issue with a view to resolving it in the v4.7.0. It's not clear to me know what you are asking for! Sorry. If you want a student input of u to be displayed as û then we can use the existing texput rules.

If you want user input of u^ to indicate a variable, then this will be almost impossible. How would you then type in û^2?

Adding in support for unicode input such as û directly would have other complications, especially in maintaining over different Maxima versions.

If you (@JB74 ) can clarify what you are asking for then we can look into it further.

JB74 commented 2 months ago

Basically, we want a student to input u+some command, which is then displayed as û. This does not mean, that the input must be u^ which is then converted to û. If there is a simple way to input û as u+some command it is fine. It is just important, that the u+some command is very easy to use, since we are heavily relying on variables with a ^ - it is not only û but also other letters.

christianp commented 2 months ago

@sangwinc do you have any notion of variable name annotations in Maxima? That's how we manage this in Numbas.

hat:u for example would be displayed in TeX as \hat{u}, and wouldn't be considered equivalent to the unannotated variable u. We normally give students a hint in the prompt about how to enter such variables they're expected to use.

aharjula commented 2 months ago

No annotations in Maxima that I am aware and we really don't want to diverge too much from that. The way Numbas hat:u maps to STACK is this:

/* In question variables. */
texput(hat, lambda([exp],sconcat("\\hat{", tex1(first(exp)), "}")));

After that, the student can use hat(u) to generate that expected output, and algebraic equivalence can and will separate u from hat(u). Unless one defines that hat(x):=x; and makes those equivalent. Obviously worse as this is one character longer, but on the other hand, these are author-definable rules, not syntax constructs.

Naturally, simply being able to input û might be nice, but then the author would need to provide alternatives for those unable to do so due to wrong language keyboards and no skills related to character composition on other common layouts, and that gets tricky fast.

JB74 commented 2 months ago

I think hat(u) would be a good solution for use - especially since this works also with e.g. hat(x) or hat(i)... for which there is definitely no key on any keyboard (at least to my knowledge).

christianp commented 2 months ago

Does that have any effects on free variable detection, or variable substitution? Is there something else you have to do to say that hat(u) represents a single atom?

I mean, it looks like hat(u) is the application of a function hat to the variable u. So if I'm trying to find out which free variables are used in the expression, I have to know that hat is something special and that plain u isn't used in the expression. Or if I know that u = 3 and want to substitute that into the expression, hat(u) needs to be left alone.

You might say that $\hat{u}$ is an operation on $u$, if $u$ is a vector: it's the unit vector parallel to $u$. But there are other contexts where it isn't so clear. For example, in statistics $\hat{y}$ is the estimated value of a response variable $y$, which you don't obtain by operating on $y$.

aharjula commented 2 months ago

Well... That hat(u) is indeed a function call and acts on the variable u, and that would be seen if one would identify used variables. But as we have the option to define the function hat anyway we want we can do things to the expression before we start looking for variables.

For example, defining the function as follows and making sure it has been evaluated before variable identification would simply mean that any call hat(u) would be evaluated to a variable called hat_u, which could then be dealt with as a variable.

hat(x) := vconcat(hat_, x);

Note that that needs some additional defensive coding to deal with x not being a simple identifier... A simple predicate in an if should be fine, and one can leave the non-identifiers as they were.

Naturally, one can always use subst to modify the expression if one wants, maybe to be more selective in actions:

(%i1) ans1: hat(u) + u;
(%o1)                             hat(u) + u
(%i2) subst([hat(u)=hat_u, hat(y)=hat_y], ans1);
(%o2)                              u + hat_u

These are all question-specific author decisions. The author can always define the names and representations of these "functions" as they wish, so definitions will vary based on the context. Being consistent over a set of materials would be nice, but we cannot easily be consistent over the whole STACK project as these might be used differently in different subjects/contexts.

sangwinc commented 2 months ago

I agree with @aharjula that "These are all question-specific author decisions." I'm very happy to add in meaningful additions like "vector" which is a sematic (and well-established) construct. But "hat" on the other hand just gives a notational addition. Do we need a data type for "complex pointers"? (I confess I'm not familiar with this from electrical engineering perspective.)

Just to record the state of play in this thread then.

  1. We're going to stick to the current supported character set for now.
  2. Question-specific author decisions can be made.
  3. We live with hat(x) and a texput function to display that.
sangwinc commented 2 months ago

Since most of this issue is question-specific at this point I'm going to close the issue.