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.044000ms
stack: size: 0

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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


                                                  realinterval


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

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

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

                                                        assert(set.RealInterval(-2, -1, true, true):isSubsetOf(set.RealInterval(-2, 2, false, true)) == nil)
                                                        GOOD time: 0.013000ms
                                                        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.022000ms
                                                          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.019000ms
                                                            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.228000ms
                                                              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.024000ms
                                                                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.065000ms
                                                                  stack: size: 0

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

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

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

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

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

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

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

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


                                                                                    containing ranges of expressions


                                                                                    assert(set.real:contains(x))
                                                                                    GOOD time: 0.014000ms
                                                                                    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.024000ms
                                                                                      stack: size: 0


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

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


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

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


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


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

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


                                                                                                      print(acos(x):getRealRange())
                                                                                                      nil GOOD time: 0.013000ms
                                                                                                      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.021000ms
                                                                                                        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.016000ms
                                                                                                          stack: size: 0


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


                                                                                                              (function() local x = set.real:var'x' assert(abs(x)() == abs(x)) end)()
                                                                                                              GOOD time: 0.365000ms
                                                                                                              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.162000ms
                                                                                                              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: 0.606000ms
                                                                                                              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.112000ms
                                                                                                              stack: size: 0

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


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

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


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

                                                                                                                        1/x should be disjoint

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

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

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


                                                                                                                              assert((1/x):getRealRange():contains(set.positiveReal))
                                                                                                                              GOOD time: 0.060000ms
                                                                                                                              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()