TODO do unit tests with the RealInterval / RealSubset operators

subsets
TODO don't use ":contains()" except for element testing, as in sets-of-sets
instead here use isSubsetOf


assert(set.real:isSubsetOf(set.real) == true)
GOOD time: 0.054000ms
stack: size: 0

    assert(set.positiveReal:isSubsetOf(set.real) == true)
    GOOD time: 0.501000ms
    stack: size: 0

      assert(set.negativeReal:isSubsetOf(set.real) == true)
      GOOD time: 0.070000ms
      stack: size: 0

        assert(set.integer:isSubsetOf(set.real) == true)
        GOOD time: 0.047000ms
        stack: size: 0

          assert(set.evenInteger:isSubsetOf(set.real) == true)
          GOOD time: 0.051000ms
          stack: size: 0

            assert(set.oddInteger:isSubsetOf(set.real) == true)
            GOOD time: 0.209000ms
            stack: size: 0


              assert(set.real:isSubsetOf(set.integer) == nil)
              GOOD time: 0.235000ms
              stack: size: 0

                assert(set.positiveReal:isSubsetOf(set.integer) == nil)
                GOOD time: 0.029000ms
                stack: size: 0

                  assert(set.negativeReal:isSubsetOf(set.integer) == nil)
                  GOOD time: 0.032000ms
                  stack: size: 0

                    assert(set.integer:isSubsetOf(set.integer) == true)
                    GOOD time: 0.023000ms
                    stack: size: 0

                      assert(set.evenInteger:isSubsetOf(set.integer) == true)
                      GOOD time: 0.037000ms
                      stack: size: 0

                        assert(set.oddInteger:isSubsetOf(set.integer) == true)
                        GOOD time: 0.023000ms
                        stack: size: 0


                          assert(set.real:isSubsetOf(set.evenInteger) == nil)
                          GOOD time: 0.034000ms
                          stack: size: 0

                            assert(set.positiveReal:isSubsetOf(set.evenInteger) == nil)
                            GOOD time: 0.023000ms
                            stack: size: 0

                              assert(set.negativeReal:isSubsetOf(set.evenInteger) == nil)
                              GOOD time: 0.029000ms
                              stack: size: 0

                                assert(set.integer:isSubsetOf(set.evenInteger) == nil)
                                GOOD time: 0.024000ms
                                stack: size: 0

                                  assert(set.evenInteger:isSubsetOf(set.evenInteger) == true)
                                  GOOD time: 0.029000ms
                                  stack: size: 0

                                    assert(set.oddInteger:isSubsetOf(set.evenInteger) == nil)
                                    GOOD time: 0.027000ms
                                    stack: size: 0


                                      assert(set.real:isSubsetOf(set.oddInteger) == nil)
                                      GOOD time: 0.033000ms
                                      stack: size: 0

                                        assert(set.positiveReal:isSubsetOf(set.oddInteger) == nil)
                                        GOOD time: 0.022000ms
                                        stack: size: 0

                                          assert(set.negativeReal:isSubsetOf(set.oddInteger) == nil)
                                          GOOD time: 0.095000ms
                                          stack: size: 0

                                            assert(set.integer:isSubsetOf(set.oddInteger) == nil)
                                            GOOD time: 0.033000ms
                                            stack: size: 0

                                              assert(set.evenInteger:isSubsetOf(set.oddInteger) == nil)
                                              GOOD time: 0.037000ms
                                              stack: size: 0

                                                assert(set.oddInteger:isSubsetOf(set.oddInteger) == true)
                                                GOOD time: 0.027000ms
                                                stack: size: 0


                                                  realinterval


                                                  assert(set.RealInterval(-2, -1, true, true):isSubsetOf(set.RealInterval(1, 2, true, true)) == false)
                                                  GOOD time: 0.042000ms
                                                  stack: size: 0

                                                    assert(set.RealInterval(-2, -1, true, true):isSubsetOf(set.RealInterval(-1, 2, true, true)) == nil)
                                                    GOOD time: 0.254000ms
                                                    stack: size: 0

                                                      assert(set.RealInterval(-2, -1, true, true):isSubsetOf(set.RealInterval(-2, 2, true, true)) == true)
                                                      GOOD time: 0.037000ms
                                                      stack: size: 0

                                                        assert(set.RealInterval(-2, -1, true, true):isSubsetOf(set.RealInterval(-2, 2, false, true)) == nil)
                                                        GOOD time: 0.034000ms
                                                        stack: size: 0


                                                          local A = set.RealInterval(0, 1, false, true) printbr(A, 'isSubsetOf', A) assert(A:isSubsetOf(A))
                                                          (0, 1] isSubsetOf (0, 1]
                                                          GOOD
                                                          time: 0.080000ms
                                                          stack: size: 0

                                                            realsubset


                                                            local A = set.RealSubset(0, 1, false, true) printbr(A, 'isSubsetOf', A) assert(A:isSubsetOf(A))
                                                            (0, 1] isSubsetOf (0, 1]
                                                            GOOD
                                                            time: 0.088000ms
                                                            stack: size: 0


                                                              local A = set.RealSubset(0, 1, false, true) local B = set.RealSubset{{-1, 0, true, false}, {0, 1, false, true}} printbr(A, 'isSubsetOf', B) assert(A:isSubsetOf(B))
                                                              (0, 1] isSubsetOf {[-1, 0), (0, 1]}
                                                              GOOD
                                                              time: 0.098000ms
                                                              stack: size: 0

                                                                assert(set.RealSubset(0, math.huge, false, true):isSubsetOf(set.RealSubset{{-math.huge, 0, true, false}, {0, math.huge, false, true}}))
                                                                GOOD time: 0.377000ms
                                                                stack: size: 0

                                                                  containing constants

                                                                  TODO technically that makes set.real the extended reals. should I distinguish between real and extended real?
                                                                  assert(set.real:contains(inf) == true)
                                                                  GOOD time: 0.039000ms
                                                                  stack: size: 0

                                                                    assert(set.positiveReal:contains(inf) == true)
                                                                    GOOD time: 0.199000ms
                                                                    stack: size: 0

                                                                      assert(set.negativeReal:contains(inf) == false)
                                                                      GOOD time: 0.097000ms
                                                                      stack: size: 0

                                                                        assert(set.nonNegativeReal:contains(inf) == true)
                                                                        GOOD time: 0.030000ms
                                                                        stack: size: 0

                                                                          assert(set.nonPositiveReal:contains(inf) == false)
                                                                          GOOD time: 0.026000ms
                                                                          stack: size: 0

                                                                            assert(set.positiveReal:contains(-inf) == nil)
                                                                            GOOD time: 0.312000ms
                                                                            stack: size: 0

                                                                              assert(set.negativeReal:contains(-inf) == true)
                                                                              GOOD time: 0.566000ms
                                                                              stack: size: 0

                                                                                assert(set.nonNegativeReal:contains(-inf) == nil)
                                                                                GOOD time: 0.072000ms
                                                                                stack: size: 0

                                                                                  assert(set.nonPositiveReal:contains(-inf) == true)
                                                                                  GOOD time: 0.061000ms
                                                                                  stack: size: 0


                                                                                    containing ranges of expressions


                                                                                    assert(set.real:contains(x))
                                                                                    GOOD time: 0.035000ms
                                                                                    stack: size: 0


                                                                                      x is in (-inf, inf).
                                                                                      is x in (0, inf)?
                                                                                      maybe.
                                                                                      not certainly yes (subset).
                                                                                      not certainly no (complement intersection / set subtraction is empty).
                                                                                      so return nil
                                                                                      if x's set is a subset of this set then return true
                                                                                      if x's set is an intersection of this set then return nil
                                                                                      if x's set does not intersect this set then return false

                                                                                      assert(set.positiveReal:contains(x) == nil)
                                                                                      GOOD time: 0.039000ms
                                                                                      stack: size: 0


                                                                                        assert(set.real:contains(sin(x)))
                                                                                        GOOD time: 0.921000ms
                                                                                        stack: size: 0

                                                                                          assert(set.RealSubset(-1,1,true,true):contains(sin(x)))
                                                                                          GOOD time: 0.259000ms
                                                                                          stack: size: 0


                                                                                            assert(not set.positiveReal:contains(abs(x)))
                                                                                            GOOD time: 0.873000ms
                                                                                            stack: size: 0

                                                                                              assert(set.nonNegativeReal:contains(abs(x)))
                                                                                              GOOD time: 0.075000ms
                                                                                              stack: size: 0


                                                                                                assert(set.complex:contains(x))
                                                                                                GOOD time: 0.034000ms
                                                                                                stack: size: 0


                                                                                                  (function() local x = set.RealSubset(-1,1,true,true):var'x' assert(set.real:contains(asin(x))) end)()
                                                                                                  GOOD time: 0.079000ms
                                                                                                  stack: size: 0

                                                                                                    (function() local x = set.RealSubset(-1,1,true,true):var'x' assert(set.real:contains(acos(x))) end)()
                                                                                                    GOOD time: 0.130000ms
                                                                                                    stack: size: 0


                                                                                                      print(acos(x):getRealRange())
                                                                                                      nil GOOD time: 0.032000ms
                                                                                                      stack: size: 0
                                                                                                        TODO eventually return uncertain / touches but not contains
                                                                                                        (function() local x = set.RealSubset(1,math.huge,true,true):var'x' assert(not set.real:contains(acos(x))) end)()
                                                                                                        GOOD time: 0.056000ms
                                                                                                        stack: size: 0
                                                                                                          TODO return definitely false
                                                                                                          (function() local x = set.RealSubset(1,math.huge,false,true):var'x' assert(not set.real:contains(acos(x))) end)()
                                                                                                          GOOD time: 0.048000ms
                                                                                                          stack: size: 0


                                                                                                            (function() local x = set.RealSubset(1,1,true,true):var'x' assert(set.real:contains(acos(x))) end)()
                                                                                                            GOOD time: 0.270000ms
                                                                                                            stack: size: 0


                                                                                                              (function() local x = set.real:var'x' assert(abs(x)() == abs(x)) end)()
                                                                                                              GOOD time: 1.791000ms
                                                                                                              stack: size: 7
                                                                                                              • Init
                                                                                                              • Prune
                                                                                                              • Expand
                                                                                                              • Prune
                                                                                                              • Factor
                                                                                                              • Prune
                                                                                                              • Tidy


                                                                                                              (function() local x = set.nonNegativeReal:var'x' assert(abs(x)() == x) end)()
                                                                                                              GOOD time: 0.841000ms
                                                                                                              stack: size: 8
                                                                                                              • Init
                                                                                                              • abs:Prune:apply
                                                                                                              • Prune
                                                                                                              • Expand
                                                                                                              • Prune
                                                                                                              • Factor
                                                                                                              • Prune
                                                                                                              • Tidy


                                                                                                              (function() local x = set.nonNegativeReal:var'x' assert(abs(sinh(x))() == sinh(x)) end)()
                                                                                                              GOOD time: 1.553000ms
                                                                                                              stack: size: 8
                                                                                                              • Init
                                                                                                              • abs:Prune:apply
                                                                                                              • Prune
                                                                                                              • Expand
                                                                                                              • Prune
                                                                                                              • Factor
                                                                                                              • Prune
                                                                                                              • Tidy


                                                                                                              x^2 should be positive

                                                                                                              assert((x^2):getRealRange() == set.nonNegativeReal)
                                                                                                              GOOD time: 0.082000ms
                                                                                                              stack: size: 0

                                                                                                                assert(set.nonNegativeReal:contains(x^2))
                                                                                                                GOOD time: 0.069000ms
                                                                                                                stack: size: 0


                                                                                                                  assert((Constant(2)^2):getRealRange() == set.RealSubset(4,4,true,true))
                                                                                                                  GOOD time: 0.169000ms
                                                                                                                  stack: size: 0

                                                                                                                    assert((Constant(-2)^2):getRealRange() == set.RealSubset(4,4,true,true))
                                                                                                                    GOOD time: 0.255000ms
                                                                                                                    stack: size: 0


                                                                                                                      assert(set.nonNegativeReal:contains(exp(x)))
                                                                                                                      GOOD time: 0.103000ms
                                                                                                                      stack: size: 0

                                                                                                                        1/x should be disjoint

                                                                                                                        print((1/x):getRealRange())
                                                                                                                        {[-inf, -0), (0, inf]} GOOD time: 0.099000ms
                                                                                                                        stack: size: 0

                                                                                                                          assert((1/x):getRealRange():contains(0) == false)
                                                                                                                          GOOD time: 0.074000ms
                                                                                                                          stack: size: 0

                                                                                                                            assert((1/x):getRealRange():contains(1))
                                                                                                                            GOOD time: 0.062000ms
                                                                                                                            stack: size: 0


                                                                                                                              assert((1/x):getRealRange():contains(set.positiveReal))
                                                                                                                              GOOD time: 0.072000ms
                                                                                                                              stack: size: 0

                                                                                                                                ../../sin.lua:function sin:getRealRange()
                                                                                                                                ../../sin.lua: local Is = self[1]:getRealRange()
                                                                                                                                ../../asinh.lua:asinh.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_inc
                                                                                                                                ../../atan.lua:atan.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_inc
                                                                                                                                ../../cosh.lua:cosh.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_evenIncreasing
                                                                                                                                ../../acos.lua:function acos:getRealRange()
                                                                                                                                ../../acos.lua: local Is = self[1]:getRealRange()
                                                                                                                                ../../tanh.lua:tanh.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_inc
                                                                                                                                ../../asin.lua:asin.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_pmOneInc
                                                                                                                                ../../sqrt.lua:sqrt.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_posInc_negIm
                                                                                                                                ../../log.lua:log.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_posInc_negIm
                                                                                                                                ../../acosh.lua:function acosh:getRealRange()
                                                                                                                                ../../acosh.lua: local Is = x[1]:getRealRange()
                                                                                                                                ../../atanh.lua:atanh.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_pmOneInc
                                                                                                                                ../../tan.lua:function tan:getRealRange()
                                                                                                                                ../../tan.lua: local Is = self[1]:getRealRange()
                                                                                                                                ../../cos.lua:function cos:getRealRange()
                                                                                                                                ../../cos.lua: local Is = self[1]:getRealRange()
                                                                                                                                ../../cos.lua: -- here I'm going to add pi/2 and then just copy the sin:getRealRange() code
                                                                                                                                ../../sinh.lua:sinh.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_inc
                                                                                                                                ../../abs.lua:abs.getRealRange = require 'symmath.set.RealSubset'.getRealDomain_evenIncreasing

                                                                                                                                ../../Constant.lua:function Constant:getRealRange()
                                                                                                                                ../../Expression.lua:function Expression:getRealRange()
                                                                                                                                ../../Variable.lua:function Variable:getRealRange()

                                                                                                                                ../../op/mul.lua:function mul:getRealRange()
                                                                                                                                ../../op/mul.lua: local I = self[1]:getRealRange()
                                                                                                                                ../../op/mul.lua: local I2 = self[i]:getRealRange()
                                                                                                                                ../../op/div.lua:function div:getRealRange()
                                                                                                                                ../../op/div.lua: local I = self[1]:getRealRange()
                                                                                                                                ../../op/div.lua: local I2 = self[2]:getRealRange()
                                                                                                                                ../../op/sub.lua:function sub:getRealRange()
                                                                                                                                ../../op/sub.lua: local I = self[1]:getRealRange()
                                                                                                                                ../../op/sub.lua: local I2 = self[i]:getRealRange()
                                                                                                                                ../../op/add.lua:function add:getRealRange()
                                                                                                                                ../../op/add.lua: local I = self[1]:getRealRange()
                                                                                                                                ../../op/add.lua: local I2 = self[i]:getRealRange()
                                                                                                                                ../../op/pow.lua:function pow:getRealRange()
                                                                                                                                ../../op/pow.lua: local I = self[1]:getRealRange()
                                                                                                                                ../../op/pow.lua: local I2 = self[2]:getRealRange()
                                                                                                                                ../../op/unm.lua:function unm:getRealRange()
                                                                                                                                ../../op/unm.lua: local I = self[1]:getRealRange()

                                                                                                                                ../../set/RealSubset.lua:-- commonly used versions of the Expression:getRealRange function
                                                                                                                                ../../set/RealSubset.lua:function RealSubset.getRealDomain_evenIncreasing(x)
                                                                                                                                ../../set/RealSubset.lua: local Is = x[1]:getRealRange()
                                                                                                                                ../../set/RealSubset.lua:function RealSubset.getRealDomain_posInc_negIm(x)
                                                                                                                                ../../set/RealSubset.lua: local Is = x[1]:getRealRange()
                                                                                                                                ../../set/RealSubset.lua:function RealSubset.getRealDomain_pmOneInc(x)
                                                                                                                                ../../set/RealSubset.lua: local Is = x[1]:getRealRange()
                                                                                                                                ../../set/RealSubset.lua:function RealSubset.getRealDomain_inc(x)
                                                                                                                                ../../set/RealSubset.lua: local Is = x[1]:getRealRange()
                                                                                                                                ../../set/RealInterval.lua: local I = x:getRealRange()