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

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

        assert(set.integer:isSubsetOf(set.real) == true)
        GOOD time: 0.008000ms
        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.005000ms
              stack: size: 0

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

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

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

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

                        assert(set.oddInteger:isSubsetOf(set.integer) == true)
                        GOOD time: 0.005000ms
                        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.008000ms
                              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.010000ms
                                  stack: size: 0

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


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

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

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

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

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

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


                                                  realinterval


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

                                                    assert(set.RealInterval(-2, -1, true, true):isSubsetOf(set.RealInterval(-1, 2, true, true)) == nil)
                                                    GOOD time: 0.008000ms
                                                    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.007000ms
                                                        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.015000ms
                                                          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.020000ms
                                                            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.025000ms
                                                              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.059000ms
                                                                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.010000ms
                                                                  stack: size: 0

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

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

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

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

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

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

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

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


                                                                                    containing ranges of expressions


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


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

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


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

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


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


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

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


                                                                                                      print(acos(x):getRealRange())
                                                                                                      nil GOOD time: 0.018000ms
                                                                                                      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.018000ms
                                                                                                        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.011000ms
                                                                                                          stack: size: 0


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


                                                                                                              (function() local x = set.real:var'x' assert(abs(x)() == abs(x)) end)()
                                                                                                              GOOD time: 0.326000ms
                                                                                                              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.465000ms
                                                                                                              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.628000ms
                                                                                                              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.123000ms
                                                                                                              stack: size: 0

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


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

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


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

                                                                                                                        1/x should be disjoint

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

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

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


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