x = var'x'
GOOD time: 0.019000ms
stack: size: 0

    
    

    y = func('y', {x}, x^2)
    GOOD time: 0.190000ms
    stack: size: 0
      TODO what to display...
      
      
      y = x
      
      
      y(x) = x
      
      
      y(x) := x
      
      

      print(y(x))
      $y\left( x\right)$ GOOD time: 0.036000ms
      stack: size: 0

        print(y(x)())
        ${x}^{2}$ GOOD time: 0.953000ms
        stack: size: 11
        • Init
        • y:Prune:apply
        • Prune
        • ^:Expand:integerPower
        • Expand
        • +:Prune:combineConstants
        • *:Prune:combinePows
        • Prune
        • Factor
        • Prune
        • Tidy

        printbr(y:defeq())
        ${y\left( x\right)} = {{x}^{2}}$
        GOOD
        time: 0.119000ms
        stack: size: 0

          assert(UserFunction.registeredFunctions.y == y)
          GOOD time: 0.012000ms
          stack: size: 0

            
            
            if UserFunction is not a Variable then this is invalid
            
            
            because you cannot have Functions as Variables in the arg list
            
            
            f = func('f', {x, y}, x*y)
            
            
            print(f:defeq())
            
            
            assert(UserFunction.registeredFunctions.f == f)
            
            

            
            
            instead, if UserFunction returns Functions, this is what you would see
            
            
            and with this the derivative evaluation is obvious
            
            

            f = func('f', {x}, x*y(x))
            GOOD time: 0.057000ms
            stack: size: 0

              print(f:defeq())
              ${f\left( x\right)} = {{{x}} {{y\left( x\right)}}}$ GOOD time: 0.229000ms
              stack: size: 0

                assert(UserFunction.registeredFunctions.f == f)
                GOOD time: 0.016000ms
                stack: size: 0

                  
                  
                  diff() is partial derivative
                  
                  
                  totalDiff() is total derivative
                  
                  

                  
                  
                  total derivative evaluation
                  
                  
                  substitute chain rule for all terms
                  
                  
                  df/dx, when simplified, does not go anywhere, because f is dependent on x
                  
                  
                  for that reason, I can just build the equality f:eq(f.def) and apply :diff() to the whole thing:
                  
                  

                  print(f:defeq():diff(x):prune())
                  ${{{3}} {{{x}^{2}}}} = {{{3}} {{{x}^{2}}}}$ GOOD time: 2.768000ms
                  stack: size: 12
                  • f:Prune:apply
                  • y:Prune:apply
                  • +:Prune:combineConstants
                  • *:Prune:combinePows
                  • y:Prune:apply
                  • +:Prune:combineConstants
                  • *:Prune:combinePows
                  • Derivative:Prune:self
                  • Derivative:Prune:eval
                  • Derivative:Prune:self
                  • Derivative:Prune:eval
                  • Derivative:Prune:eval
                  but TODO wrt total derivatives ... diff(y) ...
                  
                  
                  y(x) above is a UserFunction subclass
                  
                  
                  which means it isn't a Variable
                  
                  
                  which means you can't diff(y) ...
                  
                  
                  though you could diff(y(x)) ...
                  
                  
                  but that would be diff'ing wrt expressions, which I don't have support for
                  
                  

                  print(f:defeq():diff(y):prune())
                  BAD
                  [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: attempt to call a table value
                  stack traceback:
                  /home/chris/Projects/lua/symmath/tests/unit/unit.lua:260: in function
                  [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: in function 'clone'
                  [string "/home/chris/Projects/lua/symmath/Expression.lua"]:46: in function 'clone'
                  [string "/home/chris/Projects/lua/symmath/Expression.lua"]:46: in function 'clone'
                  [string "/home/chris/Projects/lua/symmath/op/mul.lua"]:90: in function 'flatten'
                  [string "/home/chris/Projects/lua/symmath/Expression.lua"]:327: in function '__mul'
                  [string "/home/chris/Projects/lua/symmath/op/pow.lua"]:58: in function 'evaluateDerivative'
                  [string "/home/chris/Projects/lua/symmath/Derivative.lua"]:367: in function 'func'
                  [string "/home/chris/Projects/lua/symmath/visitor/Visi..."]:224: in function 'apply'
                  [string "/home/chris/Projects/lua/symmath/visitor/Visi..."]:183: in function 'apply'
                  [string "/home/chris/Projects/lua/symmath/Derivative.lua"]:367: in function 'func'
                  [string "/home/chris/Projects/lua/symmath/visitor/Visi..."]:224: in function 'prune'
                  [string "print(f:defeq():diff(y):prune())"]:1: in main chunk
                  /home/chris/Projects/lua/symmath/tests/unit/unit.lua:252: in function
                  [C]: in function 'xpcall'
                  /home/chris/Projects/lua/symmath/tests/unit/unit.lua:251: in function 'exec'
                  func.lua:65: in function 'cb'
                  [string "/home/chris/Projects/lua/ext/timer.lua"]:101: in function 'timer'
                  func.lua:6: in main chunk
                  [C]: at 0x5569e268c390
                  time: 1.136000ms
                  stack: size: 7
                  • f:Prune:apply
                  • y:Prune:apply
                  • +:Prune:combineConstants
                  • *:Prune:combinePows
                  • y:Prune:apply
                  • +:Prune:combineConstants
                  • *:Prune:combinePows

                  print(f:defeq():diff(y(x)):prune())
                  ${0} = {0}$ GOOD time: 1.296000ms
                  stack: size: 15
                  • f:Prune:apply
                  • y:Prune:apply
                  • +:Prune:combineConstants
                  • *:Prune:combinePows
                  • y:Prune:apply
                  • y:Prune:apply
                  • +:Prune:combineConstants
                  • *:Prune:combinePows
                  • Derivative:Prune:other
                  • *:Prune:apply
                  • Derivative:Prune:eval
                  • Derivative:Prune:other
                  • *:Prune:apply
                  • Derivative:Prune:eval
                  • Derivative:Prune:eval

                  
                  

                  s = var's'
                  GOOD time: 0.014000ms
                  stack: size: 0

                    t = var't'
                    GOOD time: 0.007000ms
                    stack: size: 0

                      x = func('x', {s,t})
                      GOOD time: 0.031000ms
                      stack: size: 0

                        y = func('y', {s,t})
                        GOOD time: 0.026000ms
                        stack: size: 0

                          f = func('f', {x,y})
                          BAD
                          [string "/home/chris/Projects/lua/symmath/UserFunction..."]:140: args must be a table of Variables
                          stack traceback:
                          /home/chris/Projects/lua/symmath/tests/unit/unit.lua:260: in function
                          [C]: in function 'assert'
                          [string "/home/chris/Projects/lua/symmath/UserFunction..."]:140: in function 'func'
                          [string "f = func('f', {x,y})"]:1: in main chunk
                          /home/chris/Projects/lua/symmath/tests/unit/unit.lua:252: in function
                          [C]: in function 'xpcall'
                          /home/chris/Projects/lua/symmath/tests/unit/unit.lua:251: in function 'exec'
                          func.lua:65: in function 'cb'
                          [string "/home/chris/Projects/lua/ext/timer.lua"]:101: in function 'timer'
                          func.lua:6: in main chunk
                          [C]: at 0x5569e268c390
                          time: 0.063000ms
                          stack: size: 0
                            ∂f/∂x
                            print(f:diff(x):prune())
                            BAD
                            [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: attempt to call a table value
                            stack traceback:
                            /home/chris/Projects/lua/symmath/tests/unit/unit.lua:260: in function
                            [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: in function 'clone'
                            [string "/home/chris/Projects/lua/symmath/Derivative.lua"]:365: in function 'func'
                            [string "/home/chris/Projects/lua/symmath/visitor/Visi..."]:224: in function 'prune'
                            [string "print(f:diff(x):prune())"]:1: in main chunk
                            /home/chris/Projects/lua/symmath/tests/unit/unit.lua:252: in function
                            [C]: in function 'xpcall'
                            /home/chris/Projects/lua/symmath/tests/unit/unit.lua:251: in function 'exec'
                            func.lua:65: in function 'cb'
                            [string "/home/chris/Projects/lua/ext/timer.lua"]:101: in function 'timer'
                            func.lua:6: in main chunk
                            [C]: at 0x5569e268c390
                            time: 0.192000ms
                            stack: size: 0
                              ∂f/∂y
                              print(f:diff(y):prune())
                              BAD
                              [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: attempt to call a table value
                              stack traceback:
                              /home/chris/Projects/lua/symmath/tests/unit/unit.lua:260: in function
                              [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: in function 'clone'
                              [string "/home/chris/Projects/lua/symmath/Derivative.lua"]:365: in function 'func'
                              [string "/home/chris/Projects/lua/symmath/visitor/Visi..."]:224: in function 'prune'
                              [string "print(f:diff(y):prune())"]:1: in main chunk
                              /home/chris/Projects/lua/symmath/tests/unit/unit.lua:252: in function
                              [C]: in function 'xpcall'
                              /home/chris/Projects/lua/symmath/tests/unit/unit.lua:251: in function 'exec'
                              func.lua:65: in function 'cb'
                              [string "/home/chris/Projects/lua/ext/timer.lua"]:101: in function 'timer'
                              func.lua:6: in main chunk
                              [C]: at 0x5569e268c390
                              time: 0.169000ms
                              stack: size: 0
                                ∂f/∂x ∂x/∂s + ∂f/∂y ∂y/∂s
                                print(f:diff(s):prune())
                                BAD
                                [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: attempt to call a table value
                                stack traceback:
                                /home/chris/Projects/lua/symmath/tests/unit/unit.lua:260: in function
                                [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: in function 'clone'
                                [string "/home/chris/Projects/lua/symmath/Derivative.lua"]:365: in function 'func'
                                [string "/home/chris/Projects/lua/symmath/visitor/Visi..."]:224: in function 'prune'
                                [string "print(f:diff(s):prune())"]:1: in main chunk
                                /home/chris/Projects/lua/symmath/tests/unit/unit.lua:252: in function
                                [C]: in function 'xpcall'
                                /home/chris/Projects/lua/symmath/tests/unit/unit.lua:251: in function 'exec'
                                func.lua:65: in function 'cb'
                                [string "/home/chris/Projects/lua/ext/timer.lua"]:101: in function 'timer'
                                func.lua:6: in main chunk
                                [C]: at 0x5569e268c390
                                time: 0.308000ms
                                stack: size: 0
                                  ∂f/∂x ∂x/∂t + ∂f/∂y ∂y/∂t
                                  print(f:diff(t):prune())
                                  BAD
                                  [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: attempt to call a table value
                                  stack traceback:
                                  /home/chris/Projects/lua/symmath/tests/unit/unit.lua:260: in function
                                  [string "/home/chris/Projects/lua/symmath/Expression.lua"]:49: in function 'clone'
                                  [string "/home/chris/Projects/lua/symmath/Derivative.lua"]:365: in function 'func'
                                  [string "/home/chris/Projects/lua/symmath/visitor/Visi..."]:224: in function 'prune'
                                  [string "print(f:diff(t):prune())"]:1: in main chunk
                                  /home/chris/Projects/lua/symmath/tests/unit/unit.lua:252: in function
                                  [C]: in function 'xpcall'
                                  /home/chris/Projects/lua/symmath/tests/unit/unit.lua:251: in function 'exec'
                                  func.lua:65: in function 'cb'
                                  [string "/home/chris/Projects/lua/ext/timer.lua"]:101: in function 'timer'
                                  func.lua:6: in main chunk
                                  [C]: at 0x5569e268c390
                                  time: 0.101000ms
                                  stack: size: 0
                                    TODO I need something to represent ∂/∂x "the def of f", rather than ∂/∂x "f", which is zero.
                                    
                                    
                                    in contrast ∂/∂x "the def of f" would be a placeholder (in absense of f's provided definition)