From: Thomas Walker Lynch Date: Tue, 7 Jul 2026 18:25:40 +0000 (+0000) Subject: seems to be a bit messed up for the divide section X-Git-Url: https://git.reasoningtechnology.com/machine%20fig.png?a=commitdiff_plain;h=216d70cd7338d647e82ffc3d0d5b877a63573879;p=TM-2026 seems to be a bit messed up for the divide section --- diff --git a/document/TM-2026.html b/document/TM-2026.html index 43a8e0b..d42b437 100644 --- a/document/TM-2026.html +++ b/document/TM-2026.html @@ -1025,7 +1025,10 @@

We pass our two natural number ASTs to this composer, and we get as a result a newly synthesized AST.

- (defparameter *primitive-five-minus-3-ast* (primitive-compose-subtract *five-ast* *three-ast*)) + (defparameter + *primitive-five-minus-3-ast* + (primitive-compose-subtract *five-ast* *three-ast*) + ) ;; *primitive-five-minus-3-ast* evaluates to: ;; '(progn @@ -1105,15 +1108,19 @@

This technique of composing Turing Machine programs in the presence of simplification is closely related to that of symbol computation and expression simplification that we find in math tools such as Mathematica. We can imagine our Turing Machines as functions with names, and then symbolic computation leave them unevaluated as here. Then the the Mathematica Simplify is the compiler optimization simplifier as above. A difference in these two systems is that of the functions being reduced to Turing Machine head and tape transport unit commands.

+

The multiplicative inverse of the additive identity

-

The multiplicative inverse of the additive identity

- -

Generally it is more efficient to perform arithmetic in the first order. Also, it is easier to write Turing Machine control programs is we take Natural Number arithmetic as already available, say, from a subroutine library. Where second order computation becomes useful, is in places where a result can not be computed.

+

+ Generally it is more efficient to perform arithmetic in the first order. Also, it is easier to write Turing Machine control programs if we take Natural Number arithmetic as already available, say, from a subroutine library. Where second order computation becomes useful is in places where a result cannot be computed. +

-

The IEEE 754 floating-point standard includes error algebra tags. These are explored in depth by Popova, Evgenija D. "On a Formally Correct Implementation of IEEE Computer Arithmetic." Journal of Universal Computer Science 1, no. 7 (1995): 560-569. This is a form of second order arithmetic, because each of the error tags is standing in for a machine that did not complete. When a computation fails to result in a first order object, this becomes a gateway for replacing the result with a second order object. +

+ The IEEE 754 floating point standard includes error algebra tags. These are explored in depth by Popova, Evgenija D. "On a Formally Correct Implementation of IEEE Computer Arithmetic." Journal of Universal Computer Science 1, no. 7 (1995): 560-569. This is a form of second order arithmetic, because each of the error tags is standing in for a machine that did not complete. When a computation fails to result in a first order object, this becomes a gateway for replacing the result with a second order object.

-

Let us take for an example, the multiplicative inverse of the additive identity, as an example, AKA division by zero. In the second order, when we divide, say 6/0, the machine will not reduce. It will return a second order value:

+

+ Let us take the multiplicative inverse of the additive identity as an example, AKA division by zero. In the second order, when we divide, say 6/0, the machine will not reduce. It will return a second order value: +

(divide 6 0) @@ -1126,32 +1133,127 @@

The result will be:

+ - (multiple 2 (divide 0 0)) + (multiply 2 (divide 0 0)) -

There is no special help here. The divide machine can not be run to produce a value as any value from the field assigned to it would lead to contradictions. For other values, x·y=q operations, when given an x and a q value, there is only one possible y value, and it can be recovered with q/x. However, when x is zero, and only when it is zero, q is solely determined by x independent of y, so y is ignored, it could be any value. There is no way to recover it from q/x. +

+ There is no special help here. The divide machine cannot be run to produce a value, as any value from the field assigned to it would lead to contradictions. For other values, x \cdot y = q operations, when given an x and a q value, there is only one possible y value, and it can be recovered with q/x. However, when x is zero, and only when it is zero, q is solely determined by x independent of y, so y is ignored; it could be any value. There is no way to recover it from q/x.

-

We have been defining a function as a Turing Machine given inputs on its tape, doing a computation, running until the halt state, then stopping. For example, consider a Turing Machine given the natural number, t, we would denote this as y = f(t), where t is the initial value of the tape, and y is the value left on the tape after the machine halts. +

+ We have been defining a function as a Turing Machine given inputs on its tape, doing a computation, running until the halt state, then stopping. For example, consider a Turing Machine given the natural number, t, we would denote this as y = f(t), where t is the initial value of the tape, and y is the value left on the tape after the machine halts.

-

Now suppose consider a variation of our one variable function example. Instead of placing t on the tape as input, suppose that we define a new Turing Machine, say \dot{f}, where the initial tape is given a value, and that t is the count of the number of times we call \dot{f} without changing the tape. Thus after one call to \dot{f}, the tape will have the value of f(1), after two calls it will have the value f(2), etc. Then apparently the machine \dot{f} adds the first finite difference of the function to the tape upon each call. +

+ Now consider a variation of our one variable function example. Instead of placing t on the tape as input, suppose that we define a new Turing Machine, say F, where the initial tape is given a value, and that t is the count of the number of times we call F without changing the tape. Thus after one call to F, the tape will have the value of f(1), after two calls it will have the value f(2), etc. Then apparently the machine F adds the first finite difference of the function to the tape upon each call.

-

Now imagine that we have a second machine \dot{g} that also creates the next value of a function of natural numbers, each time it is called. And furthermore we would like to know the function, (divide \dot(f} \dot{g}).

+

+ Now imagine that we have a second machine G that also creates the next value of a function of natural numbers, each time it is called. And furthermore we would like to know the function resulting from the division of these functions, (divide F G). +

-

This is all stated rather abstractly, so let us consider an example. Suppose that f(t) = 2^t - 14, and that g(u) = u - 9. Here the free variables, which are the call counts, are independent. So when doing the division we don't know how many times \dot{f} and \dot{g} were called, and the call counts can be different. For the division to resolve we describe the synchronization between t and u. So that our example may continue, let us suppose that u = 3t. That says that each time \dot{f} is called, \dot{g} will be called three times. +

+ This is all stated rather abstractly, so let us consider an example. Suppose that our machines evaluate the functions f(t) = 2^t - 32, and g(u) = u - 15. Here the free variables, which are the call counts, are independent. So when doing the division we do not know how many times F and G were called, and the call counts can be different. For the division to resolve, we describe the synchronization between t and u. So that our example may continue, let us suppose that u = 3t. That says that each time F is called, G will be called three times.

-

So for the first differences, we have \dot{f} = 2^t. The initial value when t is zero, the value written to the initial tape, will be -14. Also, then \dot{g} = 1 the initial value on the tape will be -9. We got the initial values by putting zero for t into the functions, f and g. +

+ So for the first step, the initial value when t is zero, the value written to the initial tape, will be -31. Also, the initial value on the tape for the denominator will be -15. We got the initial values by putting zero for t into the functions, f and g.

-

So then calling the machines 4 times results in the following values:

+

+ Let us observe the raw integer sequence this generates over 10 steps. By retaining the unreduced fractions resulting from cross multiplication, we expose the underlying structural patterns driving the division. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Call Count (t)Quotient f(t) / g(3t)1st Forward DiffExtrapolated 1st Forward Diff
0-31/-1578/18078/180
1-30/-1266/10866/108
2-28/-948/5448/54
3-24/-624/1824/18
4-16/-3Undefined-6/0
5(divide 0 0)Undefined-42/0
632/396/18-84/18
796/6480/54-132/54
8224/91632/108-186/108
9480/124704/180-246/180
+ +

+ Notice what happens at step 5. The first order machine crashes because the raw arithmetic zeroes out, leaving the indeterminate (divide 0 0). Because computing the first difference requires reading adjacent values, the difference sequence fails early at step 4, unable to look across the undefined gap. +

+

+ However, if a person observes the unreduced fractions before the crash, distinct structural patterns emerge. The denominators of the differences (180, 108, 54, 18) decrease by -72, -54, and -36. This forms a perfect parabola with a constant second difference of 18. Extending this sequence yields denominators of 0 and 0. +

+

+ Similarly, the numerators (78, 66, 48, 24) decrease by an expanding arithmetic progression (-12, -18, -24), which implies a constant second difference of -6. Continuing this pattern yields -30 and -36 for the next steps. Applying these gives extrapolated numerators of -6 and -42. +

- +

+ By isolating the sequences, we fill the logical holes with the extrapolated differences of -6/0 and -42/0. The reason this works is that though the first order value goes to zero over zero, constructing the logic from the underlying finite differences separates the operation into predictable polynomials. Even though the discrete quotient still hits a division by zero at the gap, these isolated polynomials give a second order composer the continuous structural geometry needed to bridge it. +

Address diff --git a/document/divide_0_0_example.png b/document/divide_0_0_example.png new file mode 100644 index 0000000..2ab5f66 Binary files /dev/null and b/document/divide_0_0_example.png differ