動かない式を動かす(nnsolve その4)

まず,次をご覧ください.

(%i1) f:((x-1/x)^2+(y^2-4*y+5)^3+(z+1)^2/z^4<=1)%and(x<0);
                                2
                         (z + 1)      2           3        1 2
(%o1)      (x < 0) %and (-------- + (y  - 4 y + 5)  + (x - -)  <= 1)
                             4                             x
                            z

人間が見るとバレバレですが,ストレートな qepmax では

(%i2) qe([],f);
                                  2  6  4       2  5  4       2  4  4
(%o2) (x < 0) %and (z < 0) %and (x  y  z  - 12 x  y  z  + 63 x  y  z
        2  3  4        2  2  4        2    4    4  4        2  4    4    2  2
 - 184 x  y  z  + 315 x  y  z  - 300 x  y z  + x  z  + 122 x  z  + z  + x  z
      2      2
 + 2 x  z + x  = 0)

までです.

一方,nnsolve では

(%i3) nnsolve(f);
(%o3)            (x + 1 = 0) %and (y - 2 = 0) %and (z + 1 = 0)

のように解けます.

より端的な例は

(%i6) qe([],a^2+b^2+c^2+d^2=0);
                              2    2    2    2
(%o6)                        d  + c  + b  + a  = 0
(%i7) nnsolve(a^2+b^2+c^2+d^2=0);
(%o7)           (a = 0) %and (b = 0) %and (c = 0) %and (d = 0)

といったものです.

こうした「動かない式を動かす」ために作ったのが ncond です.

ncond(f):=(f)%and(
substpart("%and",map(lambda([q],qe(q,f)),
fullmap(lambda([x],[E,x]),
delete([],full_listify(powerset(setify(listofvars(f))))))),0))$

これは,所謂,必要条件を付加する関数で

(%i8) ncond(a^2+b^2+c^2+d^2=0);
                                   2    2                          2    2
(%o8) (a = 0) %and (b = 0) %and (b  + a  = 0) %and (c = 0) %and (c  + a  = 0)
        2    2             2    2    2                          2    2
 %and (c  + b  = 0) %and (c  + b  + a  = 0) %and (d = 0) %and (d  + a  = 0)
        2    2             2    2    2             2    2
 %and (d  + b  = 0) %and (d  + b  + a  = 0) %and (d  + c  = 0)
        2    2    2             2    2    2             2    2    2    2
 %and (d  + c  + a  = 0) %and (d  + c  + b  = 0) %and (d  + c  + b  + a  = 0)
(%i9) nns(qe([],%));
(%o9)          (a = 0) %and (b = 0) %and (c = 0) %and (d = 0)
(%i10) ncond(f);
(%o10) (x < 0) %and (x + 1 = 0) %and (y - 2 = 0)
        2  6       2  5       2  4        2  3        2  2        2      4
 %and (x  y  - 12 x  y  + 63 x  y  - 184 x  y  + 315 x  y  - 300 x  y + x
        2
 + 122 x  + 1 = 0) %and (z < 0) %and (z + 1 = 0)
        4  4      2  4    4    2  2      2      2
 %and (x  z  - 2 x  z  + z  + x  z  + 2 x  z + x  = 0)
        6  4       5  4       4  4        3  4        2  4          4        4
 %and (y  z  - 12 y  z  + 63 y  z  - 184 y  z  + 315 y  z  - 300 y z  + 124 z
                                  2
    2                      (z + 1)      2           3        1 2
 + z  + 2 z + 1 = 0) %and (-------- + (y  - 4 y + 5)  + (x - -)  <= 1)
                               4                             x
                              z
(%i11) nns(qe([],%));
(%o11)            (x + 1 = 0) %and (y - 2 = 0) %and (z + 1 = 0)

となります.