As usual in MATLAB, if you are not using Simulink or MATLAB Coder, then the type of a variable is dynamic, and anything on the right side of an assignment completely overwrites whatever was in the left side of the assignment if it is an unindexed variable.
That code is the same as
assignin('caller', 'a', sym('a', 'real'))
executed inside the syms function. So what is being assigned to a is the result of the sym function. MATLAB is not making a symbol-table entry marked as real: MATLAB is assigning an object to the MATLAB variable a
What properties does the object have? It turns out that the object does not store any information about assumptions. Instead, each symbolic object at the MATLAB level has amain properties: the s field which is a MATLAB character vector that is a reference to something that exists inside the Symbolic Engine.
When a + 1 is executed at the MATLAB level, the plus() operator is executed on the symbolic object (because the MATLAB level variable is a symbolic object), and the internal symbolic reference is looked up, and looks something like '_symans_[[32,0,59723]]' and that the 1 is converted to symbolic and has a similar symengine vector, and the two character vectors are passed to the symbolic engine. The symbolic engine looks them up in its internal tables and figures out how to add the two.
When you do
then 2 is converted to symbolic number, creating a symbolic object with an s field like '_symans_[[32,0,59724]]' and the 1i is converted to symbolic number, getting something much the same in the s field, and the two _symans values are passed to the symbolic engine which does the appropriate work and returns a new character internal reference character vector that is stored in the s field of a symbolic object. Then, that symbolic object overwrites the MATLAB level object without ever "informing" the existing MATLAB level object, because in MATLAB assignment of an unindexed variable only involves the existing content to the extent that the existing content has its reference count reduced and might possibly be deleted.
When the sym('a','real') part was done, the name 'a' was passed to the symbolic engine to ask for its reference to symbolic engine variable named a and the assumption 'real' and the symbolic engine reference are sent to the symbolic engine, and the symbolic engine marks its internal symbolic engine variable a with the assumption -- the assumption makes no change at the MATLAB level (but might potentially return a different internal reference to be stored.) The MATLAB level has no idea what assumptions are stored against which expressions.
Remember that it is perfectly valid to do
If you try to interpret this as saying that some kind of absolute variable named a exists at the MATLAB level, and should thereafter have all the properties from the assumptions, then you come to the conclusion that you must be asserting an identity, that a is a value such that a and a - 1 are the same value . You must, in other words, be asserting that a is one of -infinity, +infinity, or NaN ("undefined" as it is known to the symbolic engine.) But with the positivity constraint, you would have to be narrowing that down to say that a must be positive, so the combination would require that a is +infinity . This is, of course, as much incorrect at the MATLAB level as would be the case for saying that
"must" be asserting that a becomes the set of values such that a = 2 and a = 1 both hold -- that just isn't the case !
At the numeric level like that, when the a - 1 is seen in the second line, the current content of a is copied into the expression, and (content of a) - 1 is executed, and the result is stored over top of a .
Just so, symbolically, when you do
then when you get to the a - 1 part, the current content of a is copied into the expression, with that being a reference to a symbolic engine variable, and then the - 1 part is executed in the symbolic level, and a new symbolic reference is returned, and that symbolic reference overwrites what is stored at the MATLAB level. The new symbolic engine reference returned after the a - 1 is to something that lives in the symbolic engine and has a reference to the symbolic engine variable a and a subtraction, but there is a distinction between the symbolic engine variable a and the MATLAB level variable a
Thus, symbolic variables have exactly the same semantics as numeric variables: content is copied in as needed on the right-hand side, new values are created as needed by the calculation on the right, and the new value overwrites the variable on the left side without the current content of the variable on the left side having anything to say about the matter.
... and as usual, you can force the current variable to be permitted to have a say in the matter by using
which would go through the subsasgn method associated with the existing a variable and allowing that method to do whatever is meaningful under the circumstances.
Allowing syms a postive to have influence on what happens with a = sym(2)*1i would require a complete change to MATLAB assignment semantics.
And you would have to figure out how to deal with syms a positive; a = a - 1 . For example syms a positive is the same as a = sym('a'); assume(a > 0) so to maintain those constraints in the face of a = a - 1 should the result be that a is still just a name, but that the assumption on a gets updated to (a > 1) and otherwise the -1 part should be discarded ????