Menu

#4749 Declaring a symbol both real and complex or real and imaginary

None
maybe-fixed
nobody
5
6 days ago
2026-06-01
No

Maxima allows declaring a symbol both real and complex and even both real and imaginary. I think that in the second case, it should at least issue a warning, if not an error.

For the first case, where a symbol is declared both real and complex, Maxima behaves differently across csign, rectform and featurep:

(%i1) declare(x, real, x, complex);
(%o1) done

(%i2) csign(x);
(%o2) complex

(%i3) rectform(x);
(%o3) x

(%i4) featurep(x, real);
(%o4) true

(%i5) featurep(x, complex);
(%o5) true

These functions all have a different concept ...

Discussion

  • Stavros Macrakis

    Agreed this is a problem. declare(x,real,x,complex) should report that there is an inconsistency, just as assume(x>0,x<0) does. Unfortunately, the return value of declare is always "done" (except when the property is unknown, when it raises an error).

    Since the return value of declare gives no information, perhaps we can presume that code (other than the test suite) never looks at it, and we can redefine declare to be consistent with assume, like this:

    assume(x>0,x<0) => [x>0, inconsistent]
    declare(x,real,x,complex) => [kind(x,real),inconsistent]
    

    And wouldn't it be grand if this were folded into assume (while continuing to support declare for backward compatibility)? :

    assume(kind(x,real),kind(x,complex)) => [kind(x,real),inconsistent]
    

    Interestingly, forget already takes the kind argument:

    declare(x,real)$facts() => [kind(x, real)]
    forget(kind(x,real)) => [kind(x, real)]
    facts() => []
    
     
    • David Scherfgen

      David Scherfgen - 2026-06-01

      I like the idea of folding kind into assume.

      Actually, declare can already fail when there's an inconsistency, like when declaring a symbol both even and odd, not only when the property is unknown. But most inconsistencies aren't detected.

      I'm not sure about real and complex. There's at least one place in Maxima's code that explicitly handles the case when a symbol is declared both real and complex (then real wins).
      It boils down to the question: How do we define complex? As a superset of real numbers? As strictly non-real? As "probably" non-real? I find it quite tricky to come up with a definition that feels correct and useful and works nicely with the existing code and featurep.

       

      Last edit: David Scherfgen 2026-06-01
      • Stavros Macrakis

        Maxima is not very consistent about all this. For example, we have the domain=real/complex variable which sounds very powerful, but in fact the only thing it affects is the simplification of (a^b)^c as far as I can tell.

        One pragmatic definition of kind(z,complex) is that imagpart(z) returns the nounform 'imagpart(z) and not 0.

        Grepping through the code, it looks as though there are three ways that the declaration is used: kindp, decl-complexp, featurep. These are used for real/complex/imaginary in the files compar (sign-any), conjugate (manifestly-XXX-p), rpart, simp. But I haven't looked at the transitive closure of function calls....

         
        • David Scherfgen

          David Scherfgen - 7 days ago

          I like your pragmatic definition.
          We should extend risplit so that it can raise errors (controlled by a flag) for expressions that do not describe real or complex numbers, for example true, false, und, ind, inf, minf, zeroa, zerob, lists, equations, inequalities, logical expressions, sets, matrices, ...
          Then we can safely rely on risplit in $featurep.

           

          Last edit: David Scherfgen 7 days ago
          • Stavros Macrakis

            Lots of things should raise errors that don't currently:

            assume(true>false)$ is(true>false) => unknown$
            sign(a=b) => pnz
            asksign({})
            

            These are not real numbers in the mathematical sense (members of R) -- in fact, they are not numbers at all: ind, und, inf, minf, zeroa, zerob, but they are real in the sense of not having a non-zero imaginary part (as opposed to infinity), which is probably what is needed by most uses.

             
  • David Scherfgen

    David Scherfgen - 7 days ago
    • status: open --> maybe-fixed
     
  • David Scherfgen

    David Scherfgen - 7 days ago

    I pushed commit [46cd19], which restores some numerical inferences, detects lots of inconsistent type declarations and greatly simplifies decl-realp. The issue "real vs. complex" is not resolved yet.

     

    Related

    Commit: [46cd19]


Log in to post a comment.