A Soliton and its owned Bions (Awareness and Mind) – part 2


3.8 Identifier Blocks, the send() Statement, and Multicellular Development

The interface programming mentioned in section 3.7 implies that there is a way to send messages from one bion to another, and that bions can be individually recognized. The easiest way to allow recognition of individual bions is by each bion having its own unique identifier. This and much more is covered in the following subsections.

3.8.1 Identifier Blocks

Assume that the state information for an intelligent particle always includes a separate identifier block that has a fixed format composed of a small number of integers (probably less than twenty integers):

  1. Let the first integer in the identifier block identify that intelligent-particle’s type: either a bion or a soliton. Note that the soliton is the awareness particle, and besides the discussion of the soliton in this section, there is much more regarding the soliton in other parts of this book.

  2. Let the second integer in the identifier block uniquely identify that intelligent particle within its intelligent-particle type:

    For bions and solitons, assume that for all bions and solitons in existence, whenever that intelligent particle was initially created by the computing-element program, it was given a sufficiently long and randomly generated integer that will serve as a unique identifier for that intelligent particle (by “sufficiently long and randomly generated” is meant that given a very large group of bions and solitons, such as all the bions and solitons in our solar system, it will be very unlikely that there are two or more intelligent particles in that group that have the same identifier value). This identifier value, once given, cannot be changed, and it will be a permanent part of that intelligent particle’s identifier block. Also, this identifier value will be referred to as being a unique identifier for that intelligent particle, even though given a large enough group of bions and solitons, such as all the bions and solitons in our galaxy, it may not actually be unique within that group.

    Note that there are several good algorithms published in the computer-science literature for generating a sequence of random numbers given some initial arbitrary seed value as the starting point for generating that sequence. And there are many different problem domains in which solution algorithms make use of randomly generated numbers. Thus, it is reasonable to assume that the computing-element program has within it one or more routines for generating random numbers, and one can also assume that random-number generation is always available when considering the kind of algorithms that might be found among learned programs.

    Likewise, one can also assume that the computing-element program has within it one or more routines for generating a seed value given the current environment of the computing element that is executing that generate-seed routine. Note that the environmental source(s) used to generate the seed value are not necessarily external to that computing element, but instead can be internal. As an example of how a very random and very-unlikely-to-be-repeated-anytime-soon seed value can be generated from within a computing element: if the generate-seed routine is being called when that computing element is currently occupied by an intelligent particle, then that generate-seed routine can compute a hash value by reading thru the entire state information of that intelligent particle, and then use the current clock-tick count—or whatever, for this purpose, is equivalent to a clock-tick count in a computing element—to either combine with or manipulate further that computed hash value to get the final seed value returned by that generate-seed routine.

  3. Let the third integer in the identifier block be either a null value or, if the intelligent particle is a bion and that bion belongs to a soliton, then this third integer is the unique identifier for that soliton.

    I think it likely, and assume that it is so, that when a soliton is created by the computing-element program, that a large number of bions are also created at the same time in nearby computing elements, and each of these created bions will have as its third integer in its identifier block that soliton’s unique identifier.

    For all the bions owned by a soliton, assume that the computing-element program, in effect, will keep these owned bions together with both themselves and their owning soliton, never allowing any of these intelligent particles to be further away from each other than some fixed distance (let the constant SOLITON_AND_ITS_OWNED_BIONS_MAX_SEPARATION_DISTANCE be this fixed distance). I estimate that the value of SOLITON_AND_ITS_OWNED_BIONS_MAX_SEPARATION_DISTANCE is about one inch (an inch is about 2½ centimeters), and this estimate is based on my second solitonic projection (see subsection 10.1.2).

    Also assume that every soliton has the same number of owned bions, and that the soliton can only interact with its owned bions, and cannot directly interact with any common particle and cannot directly interact with any intelligent particle other than its owned bions. At the same time, the soliton is, in effect, invisible to all particles in existence with the sole exception of its owned bions. The soliton’s owned bions are, in effect, that soliton’s mind. Also assume that after its creation, a soliton cannot own any other bions than those initially created for it, but neither does a soliton ever lose any of its owned bions.

  4. Beginning with the fourth integer in the identifier block, the remaining integers in the identifier block are, for a bion, user settable by that bion. Refer to these integers in the identifier block as user-settable identifiers, and refer to this sub-block within the identifier block as the user-settable identifiers block. Thus, for bions, there exists a learned-program statement that can change any of that bion’s user-settable identifiers to either a null value or some integer value. Also, when a bion is created by the computing-element program, assume that these user-settable identifiers are initialized to null values.

    I assume there is only a small number of user-settable identifiers, perhaps less than a dozen, because for the purpose of multicellular development discussed further below, I see only seven user-settable identifiers as needed. However, in the case of organizing a soliton’s owned bions (its mind), a few more than seven user-settable identifiers might be useful. For solitons themselves, I don’t see any need for user-settable identifiers, and one can assume that these user-settable identifiers always have null values for solitons.

3.8.2 The Learned-Program send() Statement: Parameters

As mentioned above, bions need a way to communicate with each other. Additionally, owned bions need a way to communicate with their soliton, and their soliton needs a way to communicate with them. To meet these needs, assume that there is a learned-program send() statement for sending a message. Also assume that each bion and each soliton has a message queue in which messages that were sent to that intelligent particle are stored there by the computing-element program to await processing by that recipient intelligent particle. However, if a recipient of a sent message is either a bion or soliton that is currently asleep (section 9.3), then assume that that message is, in effect, ignored by that recipient and not put in that recipient’s message queue. Also assume that when a bion or soliton goes to sleep, that any messages in its message queue are discarded.

Note: In this book, the data being sent to the intended recipient(s) of a message, is often referred to as the “message text”. The message text will be a part of the sent message, but not the entire message (subsection 3.8.4 details the other components of a sent message). The message text is given to the send() statement as a parameter.

Any time a learned program calls the send() statement to send a message, that sending bion or soliton must identify the intended recipient(s) of that message. When the intended recipient(s) are one or more bions, assume that the intended recipient(s) can be specified to the send() statement in one of two ways:

  1. For each intended recipient bion, give the send() statement that bion’s unique identifier which was given to that bion when it was created (this unique identifier is item 2 in the above description of a bion’s identifier block). Thus, the send() statement is given a parameter, named list_of_bions, that is a list of one or more of these unique identifiers.

    The size of list_of_bions is presumed to be limited to a small number of unique identifiers in the list. I estimate this limit at about ten unique identifiers, which will make the largest possible size of the list_of_bions about the same size as the user_settable_identifiers_block parameter which is the other way that bion recipient(s) can be specified to the send() statement. There are two reasons for limiting list_of_bions to a small size:

    • The list_of_bions, because it identifies the message recipient(s), has to be present in the sent message and will add to the total size of the sent message. However, the larger the total size of the message, the more time needed to copy that message from one computing element to the next, transmitting that message thru 3D space. Presumably, the computing-element program imposes a limit on the total size of a message, to prevent there being messages that would significantly slow down the message-transmission process.

      Note: For a computing element that receives the sent message and is holding a bion, the search time needed by that computing element to search the list_of_bions to determine if its held bion is a recipient of that message, is not a reason to keep the size of the list_of_bions small, because one can assume that—if a large list_of_bions was allowed—the list_of_bions would be sorted into ascending unique-identifier order by the computing-element program before the message is sent, and an efficient binary search would be done on that sorted list_of_bions by any computing element that receives the sent message and is holding a bion.

    • I made the above estimate of a small limit of “about ten unique identifiers” in the list_of_bions, in August 2017 when I was nearly finished with writing the 12th edition of this book. Originally I had a higher estimate. The reason I lowered my initial estimate is because, knowing everything that is currently in my book, I can’t see any need or justification for a substantially higher limit than “about ten unique identifiers”. On the one hand, there is the user_settable_identifiers_block parameter which can reach a large number of recipient bions, and the owned-minds broadcast message (subsection 5.1.1) can reach a large audience. And on the other hand, if a substantially larger list_of_bions is actually needed for some reason that I cannot currently imagine, then the same message text can be sent repeatedly, but with a different list_of_bions each time.

    OR

  2. Give the send() statement a user-settable identifiers block that has at least one of its values non-null. When the send() statement is called with this parameter, name this parameter user_settable_identifiers_block. In this case, the recipient bion(s) of this message will be those bions that have the same non-null values in the same locations in that bion’s user-settable identifiers block.

    For example, if the user_settable_identifiers_block parameter has in its first position a non-null integer value X, and in its second position a non-null integer value Y, and the remaining positions have a null value, then each recipient bion within its own user-settable identifiers block must have the same X integer value in its first position, and the same Y integer value in its second position.

Regarding messages to and from a soliton, to protect the communications integrity of the soliton, assume the following rules:

  • The only intelligent particle that can send a message to a given soliton is a bion that is owned by that soliton, and the soliton recipient of that message is always that owner. The sent message always includes the sender’s complete identifier block so that the soliton can, in effect, know from which part of its mind that message is coming from, and, if for that sender its message is supposed to be perceived in some way by that soliton’s awareness, then, in effect, route that message-content’s implied perception to the correct awareness-particle input channel(s) for that soliton (section 9.6 discusses awareness-particle input channels).

  • A soliton can only send a message to one or more of its owned bions. For example, so that a soliton can give feedback and/or guidance to a group of bions that have a specific mental function within that soliton’s mind.

For all the bions owned by a soliton, which collectively form that soliton’s mind, it is reasonable to assume that while awake there will be a lot of within-the-mind communication going on, in the form of messages sent within that mind. To protect the integrity of a soliton’s mind, assume that for any bion that is owned by a soliton, any call of the send() statement by that bion to send a message to one or more other bions must, in effect, pass a parameter to that send() statement specifying whether this is a within-the-mind communication or not: if within-the-mind, then the only bion(s) that can possibly receive the sent message are bion(s) that are also owned by that sender’s soliton; if instead, not within-the-mind is specified, then the only bion(s) that can possibly receive the sent message are bion(s) that are not owned by that sender’s soliton.

To accomplish this within-the-mind-or-not restriction on which bions can potentially receive into their message queues the sent message, regardless of how the recipient bion(s) are specified to the send() statement, assume that this within-the-mind-or-not restriction is the last test done by the computing-element program to determine if it will add the sent message to a bion’s message queue, after already determining that that bion qualifies as a recipient bion given the way the recipient bion(s) were specified to the send() statement when that message was sent.

For any bion that has received a message into its message queue from some other bion, assume that the complete identifier block of the sender is made available to the receiving bion along with that message, and also the parameter given to the send() statement by the sender to identify the recipient bion(s), either list_of_bions or user_settable_identifiers_block, is also made available to the receiving bion. After thinking over security considerations, and given what is already said above in this subsection about restrictions placed on the send() statement, and also to make processing the message easier, I believe it is best to expose all of the sender’s identifier block to the receiving bion(s) and not hide any of it.

In the case of a direct call of the send() statement by a learned program, and the message to be sent is not being sent to or from a soliton, and the message is not being sent within the mind as per the within-the-mind-or-not parameter, then an additional parameter for the send() statement is the use_this_send_distance parameter which is an integer that is used, after editing, to set the value of send_distance for the message to be sent (send_distance is explained in subsection 3.8.4). The use_this_send_distance parameter is also a parameter for some of the other learned-program statements presented in this book, including the get_relative_locations_of_bions() statement which is detailed in subsection 3.8.6. In general, a use_this_send_distance parameter value is edited before it is assigned to send_distance so that its value is not less than 1 and not more than the MAX_SEND_DISTANCE_ALLOWED_FOR_… value for that statement (for example, not more than MAX_SEND_DISTANCE_ALLOWED_FOR_SEND_STATEMENT for the send() statement, and not more than MAX_SEND_DISTANCE_ALLOWED_FOR_LOCATING_BIONS for the get_relative_locations_of_bions() statement).

Regarding the distance represented by the value of MAX_SEND_DISTANCE_ALLOWED_FOR_SEND_STATEMENT, my opinion is that this distance is at least hundreds of miles if not several thousand miles (1 mile is about 1.6 kilometers).

3.8.3 Coordinates in 3D Space, and Message Transmission thru 3D Space

Assume that, in effect, each computing element, which is extremely tiny (see chapter 1), is a cube, and these cubes are, in effect, packed tight together into a gigantic 3D array of computing elements, and this gigantic 3D array of computing elements is the 3D space within which we and the rest of our universe exists (footnote 23 gives a reason why this gigantic 3D array of computing elements itself has a cube shape). Assume that each computing element has defined in its state information this_CE’s_XYZ (CE means “computing element”), which is its 3D coordinate within this gigantic 3D array of computing elements. A computing element is uniquely identified by its XYZ coordinate, and is the only computing element in our universe that has that XYZ coordinate. As long as our universe exists, the XYZ coordinate of each computing element in our universe never changes.

The value of this_CE’s_XYZ has three components, an X coordinate, a Y coordinate, and a Z coordinate, and these three components can be accessed individually as this_CE’s_XYZ.X, this_CE’s_XYZ.Y, and this_CE’s_XYZ.Z, respectively. A computing element’s XYZ coordinate consists of three non-negative integers: a non-negative integer X for its X coordinate along the X axis, a non-negative integer Y for its Y coordinate along the Y axis, and a non-negative integer Z for its Z coordinate along the Z axis. Also, any two computing elements that are adjacent to each other along an axis (either the X, Y, or Z axis), will have their respective coordinate along that axis differ by 1. In effect, the computing elements have a standard XYZ coordinate system, the same as taught in math books, but without negative coordinates for the computing elements in our universe.

For any two computing elements, the distance between their respective XYZ coordinates can be computed using the distance formula for the distance between two XYZ points. For any two points in 3D space whose coordinates are (x1, y1, z1) and (x2, y2, z2), the distance between those two points is given by the distance formula:

square_root_of((x2 − x1)2 + (y2 − y1)2 + (z2 − z1)2)

For the distance formula, its arithmetic is signed, and each point with its three components can have one or more negative components. For example, if point A is (2, −4, 8), and point B is (1, 3, −9), then the distance between points A and B is square_root_of((1 − 2)2 + (3 − −4)2 + (−9 − 8)2), which reduces to square_root_of((−1)2 + (7)2 + (−17)2) which is square_root_of(1 + 49 + 289), which is square_root_of(339), which is about 18.412. Note that exchanging the two points in the distance formula reverses signs, but because (−n)2 = (n)2, one gets the same answer: square_root_of((2 − 1)2 + (−4 − 3)2 + (8 − −9)2) reduces to square_root_of((1)2 + (−7)2 + (17)2) which is square_root_of(1 + 49 + 289), the same as before.

In a few places in this book, likely non-integer results are assigned to the X, Y, and Z of an XYZ coordinate variable. In these cases, just assume any non-integer result is rounded to the nearest integer before that assignment. Also, in a few places in this book, an XYZ coordinate variable is said to be signed or the computation(s) involving it are said to be signed, which means that its X, Y, and Z components can have negative values.

Regarding the unit of distance used in the computing-element program: Given what is said above about the 3D coordinate system for the computing elements, the unit of distance is the side-width of a computing element, which chapter 1 estimates is 10−16 centimeters wide. Thus, about 1016 distance units is about 1 centimeter in length. Also, to be consistent with the above 3D coordinate system for the computing elements, and consistent with the distance formula applied to that 3D coordinate system, it follows that the side-width of a computing element is also the distance unit used thruout the computing-element program, including the various distance constants, variables, and parameters that I give in this book. For example, assuming that the side-width of a computing element is 10−16 centimeters, if the distance constant SOLITON_AND_ITS_OWNED_BIONS_MAX_SEPARATION_DISTANCE has a value equivalent to 2.5 centimeters, then the actual integer value of SOLITON_AND_ITS_OWNED_BIONS_MAX_SEPARATION_DISTANCE is (2.5 × 1016).

Two different Message-Transmission Algorithms

Our universe is finite, and our galaxy appears to be far away from any edge in our universe where there are no computing elements. Thus, for our galaxy’s location in this universe, let’s assume that every computing element is surrounded on all sides by other computing elements. Let’s now define what is meant in the message-transmission algorithms by the phrase adjacent computing elements: Assuming a cube shape for each computing element, a cube has six sides, and in our galaxy each computing element shares each of its six sides with an adjacent computing element. Also, assume that message transmission only happens across a shared side. Thus, each computing element in our galaxy has a total of six adjacent computing elements that it can transfer messages to and from.

Regarding message transmission thru 3D space, assume that the computing-element program has two different algorithms for message transmission:

  1. A sphere-filling message-transmission algorithm : Every computing element within send_distance of the originating computing element from which the message was sent, will receive a copy of that message (note that send_distance has the same unit of distance discussed above for the computing elements and their 3D coordinate system, which is the side-width of a computing element). In effect, a sphere of 3D space, with the center of that sphere being that originating computing element, will receive that sent message. The details of this message-transmission algorithm are given in subsection 3.8.5.

    With the sole exception of the gravity algorithm given in footnote 23, which uses the second message-transmission algorithm to send mass messages and gravity-info messages, all the message sending in this book uses this sphere-filling message-transmission algorithm to send the message. The reason, in general, is because it appears that all particles in our galaxy are moving thru 3D space, and 3D space is composed of computing elements. Also, nearby particles are typically moving relative to each other. The end result of all this particle movement is that any message that is sent from one particle to one or more other particles, is, in effect, best sent in every direction, filling a sphere, so that the designated recipient particle(s) can, in effect, be found by that message, for any recipient particle that is within the send_distance range of that message.

  2. A message-transmission algorithm that sends the message to a specific computing element : This algorithm sends the message along the shortest path from the originating computing element to the destination computing element that is identified by its XYZ coordinate. This message-transmission algorithm is only used in this book to send mass messages and gravity-info messages (see footnote 23), and the details of this message-transmission algorithm are given at the beginning of footnote 23.

In the attached footnote, I give an efficient algorithm for computing the force of gravity at each computing element, and this gravity algorithm uses the sphere-filling message-transmission algorithm to send gravity messages, and uses the other message-transmission algorithm, that sends the message to a specific computing element, to send mass messages and gravity-info messages.[23]

Note: To avoid excessive repetition, anywhere in this book where I say that a computing element does some specific action, or a particle does some specific action, it is actually the computing-element program that is, in effect, doing that action. The only exception to this rule is the soliton (awareness) which has an agency (its so-called free will) that is independent of the computing-element program. A soliton’s agency, in effect, can decide on the messages that the computing-element program will send to that soliton’s mind (the soliton’s owned bions). (As a side note regarding the soliton, the only reason for the existence of our universe that I can see, is that our universe is a structured playground for all the awarenesses that, in effect, live in our universe: the universe exists for the sake of all these awarenesses.)


footnotes

[23] In this footnote, first a message-transmission algorithm is given for sending a message to a specific computing element, and then an efficient algorithm is given for gravity. This footnote ends with a description of two approximations in the gravity algorithm, and a discussion of the gravity algorithm’s efficiency.

A Message-Transmission Algorithm for Sending a Message to a Specific Computing Element

There is no learned-program statement for sending a message to a specific computing element. Thus, intelligent particles cannot send a message to a specific computing element. Only the computing-element program can send a message to a specific computing element.

Assume the following format for any message whose recipient is a specific computing element identified by its XYZ coordinate:

  1. The message begins with a code that identifies this message to the computing-element program as using this message-transmission algorithm.

  2. sending_CE_XYZ : The XYZ coordinate of the computing element that sent this message. The sending computing element sets sending_CE_XYZ to this_CE’s_XYZ, which is that sending computing element’s XYZ coordinate.

  3. X_steps_remaining_until_at_the_recipient_CE
    Y_steps_remaining_until_at_the_recipient_CE
    Z_steps_remaining_until_at_the_recipient_CE

    The following code is executed by the sending computing element to set these three before this message is sent (recipient_CE_XYZ is the XYZ coordinate of the computing element that this message is being sent to):

    set X_steps_remaining_until_at_the_recipient_CE to (recipient_CE_XYZ.X − sending_CE_XYZ.X)
    set Y_steps_remaining_until_at_the_recipient_CE to (recipient_CE_XYZ.Y − sending_CE_XYZ.Y)
    set Z_steps_remaining_until_at_the_recipient_CE to (recipient_CE_XYZ.Z − sending_CE_XYZ.Z)

  4. The message type : The computing-element program has predefined the allowed message types for a message sent to a specific computing element. The message type, in effect, identifies the format and meaning of the message text.

  5. The message text : The data being sent to the recipient computing element.

The following block of code is executed by the computing-element program in this_CE which is the computing element that currently holds the message, and this includes the sending computing element when it is ready to send this message. In effect, this block of code is the message-transmission algorithm for any message having the above format:

if X_steps_remaining_until_at_the_recipient_CE is a negative number then

Add 1 to X_steps_remaining_until_at_the_recipient_CE and transfer this message to that adjacent computing element whose XYZ coordinate has the same Y and Z coordinates as this_CE, but that adjacent computing element’s X coordinate is one less than this_CE’s X coordinate.

else if X_steps_remaining_until_at_the_recipient_CE is a positive number then

Subtract 1 from X_steps_remaining_until_at_the_recipient_CE and transfer this message to that adjacent computing element whose XYZ coordinate has the same Y and Z coordinates as this_CE, but that adjacent computing element’s X coordinate is one more than this_CE’s X coordinate.

else if Y_steps_remaining_until_at_the_recipient_CE is a negative number then

Add 1 to Y_steps_remaining_until_at_the_recipient_CE and transfer this message to that adjacent computing element whose XYZ coordinate has the same X and Z coordinates as this_CE, but that adjacent computing element’s Y coordinate is one less than this_CE’s Y coordinate.

else if Y_steps_remaining_until_at_the_recipient_CE is a positive number then

Subtract 1 from Y_steps_remaining_until_at_the_recipient_CE and transfer this message to that adjacent computing element whose XYZ coordinate has the same X and Z coordinates as this_CE, but that adjacent computing element’s Y coordinate is one more than this_CE’s Y coordinate.

else if Z_steps_remaining_until_at_the_recipient_CE is a negative number then

Add 1 to Z_steps_remaining_until_at_the_recipient_CE and transfer this message to that adjacent computing element whose XYZ coordinate has the same X and Y coordinates as this_CE, but that adjacent computing element’s Z coordinate is one less than this_CE’s Z coordinate.

else if Z_steps_remaining_until_at_the_recipient_CE is a positive number then

Subtract 1 from Z_steps_remaining_until_at_the_recipient_CE and transfer this message to that adjacent computing element whose XYZ coordinate has the same X and Y coordinates as this_CE, but that adjacent computing element’s Z coordinate is one more than this_CE’s Z coordinate.

else this_CE is the recipient and the transfer of this message to the recipient computing element is complete.

An Efficient Gravity Algorithm

Note: In various places in this gravity algorithm, to avoid excessive repetition, I say that a computing element, or a parent, or a child, or this_CE, does some specific action. However, in all such cases, it is actually the computing-element program that is running on that computing element, that is, in effect, doing that action.

Note: because of many references, both forward and backward references, to specific paragraphs within this gravity algorithm, each paragraph in this gravity algorithm, not including the paragraphs in lists and code, is prefixed with a paragraph number, beginning with the next paragraph:

p1:: In this gravity algorithm, the level number, n, is a non-negative integer. Assume that the computing-element program defines a hierarchy of cubes for gravity. Each cube at level (n + 1) in the hierarchy is three times wider than the width of the cube at level n. The lowest level in this hierarchy is level 0, and each cube at level 0 is a single computing element, and its width is one computing-element wide. Each cube at level 1 is three computing elements wide and contains a total of 3×3×3 = 27 computing elements. The width of each cube at level n is 3n computing-element widths, and each cube at level n contains 3(3 × n) computing elements.

p2:: There is a finite number of these levels defined in the computing-element program. To get an approximation of what the largest level number is, the largest and most massive objects in our universe that appear to be held together by gravity, are the galaxies. The width of our Milky Way galaxy is roughly 100,000 light years, and our galaxy is roughly average in terms of galaxy size, so let’s guess that, for the purpose of creating gravity, the largest cube defined by the computing-element program has a width of 100,000 light years. Assuming that the width of a computing element is 10−16 centimeters wide (chapter 1), and given that one light year is a distance of about 1017 centimeters, the number of computing-element widths in 100,000 light years is ((1017 × 100,000) ÷ 10−16)) which is 1038 computing-element widths. Then, to compute the level number for a cube that has a side width of roughly 100,000 light years, find the nearest integer value for n in the equation 3n = 1038. Using my calculator, n is 80. Assume that the level number n ranges from 0 to 80 inclusive.

p3:: Also, to avoid edge cases regarding this hierarchy of cubes for gravity, let’s assume that our universe is contained within a cube of computing elements, and this universe-containing cube’s side width is an integer multiple of the side width of a cube at level 80 (assuming that 80 is the largest level number).

p4:: Each cube at level (n > 0) contains exactly 27 cubes at level (n − 1).

p5:: For each cube at level (n > 0), denote the single computing element at the center of that cube as the parent of that cube.

p6:: For each cube at level 1, the 27 computing elements in that cube are the children of that cube’s level 1 parent—one of those 27 children being that parent itself.

p7:: For each cube at level (n > 1), that level n cube’s parent has 27 children (each of these 27 children is a computing element)—one of those 27 children being that parent itself. And each of those 27 children is itself a parent at level (n − 1).

p8:: Each mass message (see paragraphs p10 and p12) is sent by the message-transmission algorithm given at the beginning of this footnote, because the recipient of each mass message is a specific computing element identified by its XYZ coordinate. The message type identifies the message as a mass message, and the message text has only two components: mm_com_XYZ which is a center-of-mass coordinate, and mm_tm which is a total-mass amount (assume that mm_tm is an integer variable). IMPORTANT: When a child sends a mass message to its parent (see paragraphs p10 and p12), and that child is its parent (the child and its parent are the same computing element), then that mass message, in effect, is sent to itself, but without actually using a message-transmission algorithm to send it to itself.

p9:: A computing element’s status of being or not being a parent at level n, for levels 1 thru 80, is only dependent on that computing element’s XYZ coordinate. Assume that shortly after each computing element came into existence, its computing-element program computed for that computing element (denote as this_CE) the levels, if any, at which this_CE is a parent (see paragraph p29 for the code to do this). And, for each level (n < 80) at which this_CE is a parent, also computed is the XYZ coordinate of that parent’s parent at level (n + 1) (see paragraph p30 for the code to compute a parent’s parent). And all this computed parent info is saved in this_CE’s state information for use by this gravity algorithm. And, immediately after computing and storing all this parent info, also assume that for each level n at which this_CE is a parent, that memory is allocated and initialized for saving the most recently received mass message from each of its 27 children at level (n − 1) (see paragraph p12; assume that each of the 27 entries is initialized to null). Also, if this_CE is not a parent at level 1, then save in this_CE’s state information the XYZ coordinate of this_CE’s parent at level 1 (see paragraph p29 for the code to do this), because this_CE will send a mass message to that parent at level 1 whenever the mass currently held by this_CE changes (see paragraph p10).

p10:: Each computing element at level 0 sends a mass message to its parent at level 1 whenever the mass currently held by that computing element changes. The mass message’s mm_com_XYZ is set to that computing element’s this_CE’s_XYZ, and mm_tm is set to the mass currently held by that computing element (this mm_tm value will be set to zero if this computing element was most recently holding a particle with a nonzero mass, but is currently not holding a particle with a nonzero mass).

p11:: Note: In this gravity algorithm, the phrase “a particle with a nonzero mass” is equivalent to the phrase “a particle with a positive mass”, because I see no reason for the computing-element program to define or allow a particle or particle type to have a negative mass as its mass attribute. Also, physics has no experimental evidence for the existence of anything, with respect to gravity, having a negative mass. Thus, assume that particles having a negative mass do not exist.

p12:: Each parent at level (n > 0) can potentially receive at any time a mass message from any of its 27 children at level (n − 1). That parent (a computing element) saves in its allocated memory for level n (see paragraph p9) the most recently received mass message from each of its 27 children at level (n − 1). Periodically, that parent examines the 27 entries in that allocated memory for level n (any null entries—see paragraph p9—are ignored), and adds up the masses into a total-mass value tm, and, if the value of tm is greater than zero, computes a center-of-mass coordinate com_XYZ for that tm value (note: this computed com_XYZ coordinate will lie within the level n cube for which it was computed). If this level n is not the maximum level number 80, then this parent at level n sends a mass message to its parent at level (n + 1): mm_tm is set to the computed tm; if the value of tm is greater than zero, then mm_com_XYZ is set to the computed com_XYZ, otherwise mm_com_XYZ is set to null. (Note: Computing the center-of-mass coordinate for 27 masses whose center-of-mass XYZ coordinate for each of those 27 masses is known, is a simple low-cost computation. For the formula, see, for example, Center of Mass for Particlesextended to three dimensions, at http://hyperphysics.phy-astr.gsu.edu/hbase/cm.html.)

p13:: Also, immediately after each parent at level (n > 0) periodically computes tm and com_XYZ (see paragraph p12), if that level n is at least MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE, then that parent at level n sends a gravity-related message, which is either a gravity-info message or a gravity message (see paragraph p15). MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE is an integer constant. I don’t know what value for MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE would be best overall, but for the sake of being able to give a value for MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE that is probably not too far from its actual value, let’s assume that a level n cube must be at least one centimeter wide before the parent of that level n cube will send gravity-related messages for that level n cube. And, assuming 10−16 centimeters is the side-width of a computing element, that means a line along an axis, of 1016 computing elements, has a length of one centimeter. And, given that the width of each cube at level n is 3n computing-element widths (see paragraph p1), then MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE is the smallest integer such that (1016 <= 3MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE) (note: <= is less than or equal). Using my calculator, MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE is 34.

p14:: Only the computing-element program, when running this gravity algorithm, can send a gravity-related message. Learned programs cannot send a gravity-related message, nor can they send a mass message. Regarding the gravity message specifically, assume that a gravity message begins with a code that identifies that message as a gravity message to the computing-element program. Note that a gravity message does not specify any recipients, because every computing element within range of a sent gravity message is a recipient and will receive that gravity message and examine its content. The criteria by which a computing element decides if it will accept or ignore a received gravity message is given in paragraph p18. Each gravity message has four components in its message text:

  • parent’s_XYZ : The originating parent’s XYZ coordinate (the parent is a computing element; that computing element sets parent’s_XYZ to this_CE’s_XYZ).

    By “originating parent” is meant the parent that either sent the gravity-info message that became this gravity message, or sent this gravity message directly (see paragraph p15).

  • parent’s_level : The level number of the originating parent.

  • center_of_mass_XYZ : The center-of-mass coordinate computed by the originating parent at level parent’s_level.

    The X, Y, and Z components of the computed center-of-mass coordinate are each rounded to the nearest integer before being assigned to center_of_mass_XYZ.X, center_of_mass_XYZ.Y, and center_of_mass_XYZ.Z, respectively. For example, if the computed X, Y, and Z components are 3.1, 7.52, and 12, respectively, then center_of_mass_XYZ.X is set to 3, center_of_mass_XYZ.Y is set to 8, and center_of_mass_XYZ.Z is set to 12.

  • total_mass : The total-mass number computed by the originating parent at level parent’s_level. Note: total_mass is an integer variable.

p15:: The parent’s_XYZ, parent’s_level, center_of_mass_XYZ, and total_mass values of a gravity-related message are set by the originating parent. However, the gravity message itself will be sent by the computing element at the center_of_mass_XYZ coordinate in that gravity message, which will most likely be a different computing element than the originating parent. Sending the gravity message from the computing element at the center_of_mass_XYZ coordinate, is done for reasons of overall efficiency, to minimize the total number of computing elements that will receive that sent gravity message. The following procedure is done whenever a parent at level (n >= MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE) is ready to send a gravity-related message, which is either a gravity-info message or a gravity message (note: >= is greater than or equal):

  1. If the center_of_mass_XYZ coordinate is not the same XYZ coordinate as the parent’s_XYZ coordinate (not being the same is most likely), then the parent uses the message-transmission algorithm given at the beginning of this footnote to send a gravity-info message to the computing element at that center_of_mass_XYZ coordinate. The message type identifies the message as a gravity-info message, and the message text has four components: parent’s_XYZ, parent’s_level, center_of_mass_XYZ, and total_mass.

    When the computing element at that center_of_mass_XYZ coordinate receives this gravity-info message, the gravity algorithm at that computing element puts together a complete gravity message, with the received parent’s_XYZ, parent’s_level, center_of_mass_XYZ, and total_mass values copied into the message text of that gravity message. Also, the send_distance for this gravity message is computed using the same “set send_distance” formula shown below in step 2. And then this gravity message is sent by that computing element using the message-transmission algorithm given in subsection 3.8.5, that, in effect, sends the message out into 3D space, filling a sphere whose radius is the send_distance for that message. Also, that computing element, in effect, sends that gravity message to itself, but without actually using a message-transmission algorithm to send it to itself.

  2. If the center_of_mass_XYZ coordinate is the same XYZ coordinate as the parent’s_XYZ coordinate (not likely, but it can happen), then complete the gravity message to be sent. Because the force of gravity between two masses decreases with the square of the distance between those two masses, compute the send_distance for this gravity message as:

    set send_distance to ((a constant defined in the computing-element program’s gravity algorithm) × square_root_of(this gravity message’s total_mass))

    The idea here is to not send a gravity message further out into 3D space than its total_mass amount can gravitationally affect in a significant way a particle of average mass.

    The above (send_distance = ((a constant) × square_root_of(total_mass))) formula was derived by simple algebra applied to Newton’s formula (see paragraph p21 for Newton’s formula for the gravitational force between two masses): First, the other mass in Newton’s formula is assumed here to be a nonzero-mass particle of average mass (perhaps this average mass is roughly the mass of a hydrogen atom), thus, in effect, the other mass is a constant (denote as k1). Also, the gravitational force on the left side of Newton’s formula is assumed here to be, in effect, another constant (denote as k2), because we want the minimum gravitational force that can affect a nonzero-mass particle of average mass in a significant way. Thus, in this case, with two constants, Newton’s formula reduces to (k2 = ((k1 × total_mass) ÷ (d2))). Then, multiply both sides by d2, and then take the square-root of both sides, giving us (send_distance = ((square_root_of(k1) ÷ square_root_of(k2)) × square_root_of(total_mass)), and, because (square_root_of(k1) ÷ square_root_of(k2)) is itself a constant, we get the above (send_distance = ((a constant) × square_root_of(total_mass))) formula.

    After computing the send_distance, the parent sends the gravity message using the message-transmission algorithm given in subsection 3.8.5, that, in effect, sends the message out into 3D space, filling a sphere whose radius is the send_distance for that message. Also, that parent, in effect, sends that gravity message to itself, but without actually using a message-transmission algorithm to send it to itself.

    Presumably, this limitation on the send_distance for a gravity message, along with a less frequent send rate as the level number n increases (see paragraph p16), prevents each computing element in our universe from being overwhelmed by too many gravity messages being received by that computing element.

p16:: In paragraph p12, I say that the parent at level n, for n > 0, periodically computes a total-mass and center-of-mass, and—if n < 80—sends this computed info in a mass message to that parent’s parent, and—see paragraph p13—sends this computed info in a gravity-related message if n >= MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE. But how often is “periodically”? More specifically, how many times per second (denote as tps) is “periodically”? It makes sense that tps decreases as n increases. For example, at the two extremes for level n > 0, 1 and 80, I think it likely that for a parent at level 1, tps is more than a billion times per second, but for a parent at level 80, tps is less than one time per second. Note that the effect of gravity has all the mass in our universe in motion relative to the computing elements (for example, our Earth is moving thru space at roughly 1/245th of lightspeed—see the footnote in subsection 3.8.6). The computing elements, in effect, are the 3D space within which we and our universe exists. Thus, the movement of an object thru 3D space is movement of that object’s particles thru the computing elements that compose that 3D space. The higher the level number n, the larger its level n cube (see paragraphs p1 and p2), and because of this greater cube size, gravitationally significant and substantial change to the periodically computed total-mass and center-of-mass for that cube by its parent, will, in general, happen over a slower time frame than for a smaller cube size.

p17:: Every computing element in our universe is a potential recipient of gravity messages. Assume that shortly after each computing element came into existence, its computing-element program computed for that computing element (denote as this_CE) the XYZ coordinates of the originating parents from which this_CE will accept gravity messages. More specifically, compute at each level n, for levels MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE thru 80 inclusive, the XYZ coordinate of the parent for the level n cube that contains this_CE, and the XYZ coordinates of the 26 parents for the level n cubes that immediately surround the level n cube that contains this_CE (to make clear what is meant by “immediately surround”, these 27 cubes together have the shape of a cube; see paragraph p32 for the code to compute the XYZ coordinates of these 27 parents at level n). The computing-element program saves into this_CE’s state information an initialized gmr entry—gmr stands for “gravity message received”—for each of these 27 parents at level n, for levels MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE thru 80 inclusive (assuming MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE is 34 and the maximum level number is 80, there are ((80 − 34) + 1) × 27 = 1,269 gmr entries in this_CE’s state information). Each gmr entry has five components: from_parent_XYZ, level_num, time_received, center_of_mass_XYZ, and total_mass. Each gmr entry is initialized as follows: from_parent_XYZ is set to the parent’s XYZ coordinate, level_num is set to the parent’s level number, and time_received, center_of_mass_XYZ, and total_mass, are each initialized to null. After all the gmr entries have been initialized, they are then sorted into ascending key order (the key of each gmr entry has two components: the from_parent_XYZ value and the level_num value). The reason for this sort is so that an efficient binary search can be used in paragraph p18 whenever a computing element receives a gravity message, to determine if that computing element has a gmr entry for that gravity message. After all the gmr entries have been initialized, and then sorted, this_CE is ready to receive gravity messages.

p18:: After the gmr entries have been initialized and then sorted (see paragraph p17), whenever a computing element (denote as this_CE) receives a gravity message, it does the following: If one of this_CE’s gmr entries has the same from_parent_XYZ and level_num values as that gravity message’s parent’s_XYZ and parent’s_level values, respectively, then set that gmr entry’s center_of_mass_XYZ and total_mass values to that gravity message’s center_of_mass_XYZ and total_mass values, respectively, and set time_received to the current time on this_CE’s internal clock; otherwise, ignore that received gravity message.

p19:: In preparation for paragraphs p21, p22, p24, and p26: First, a brief description of force vectors and the terminology used in this footnote: The tail-point XYZ coordinate and the head-point XYZ coordinate are the two end points of a force vector, and the direction of the force vector—the direction of the force—relative to the tail-point, is towards the head-point. Also, the length of the force vector (the distance between the tail-point and the head-point) is the amount of force. Thus, a force vector, described by two XYZ coordinates, represents an amount of force and the direction of that force relative to the tail-point. Also, the unit of force must be the same for any two force vectors added together, and this is directly relevant to paragraph p22 in which different kinds of force vectors are added together (each of these force vectors can contribute to moving the nonzero-mass particle held by this_CE, and this_CE’s XYZ coordinate is the tail-point for each of these force vectors). Note: the head-to-tail method for adding together force vectors is described in paragraph p26.

p20:: The current values of center_of_mass_XYZ and total_mass in each of this_CE’s gmr entries are used to compute the current gravitational force on the particle currently held by this_CE whenever this_CE begins holding a particle with a nonzero mass. For this gravitational-force calculation, ignore any gmr entry whose current total_mass value is null or zero, or whose current center_of_mass_XYZ value is the same XYZ coordinate as this_CE’s XYZ coordinate. For each gmr entry not already ignored by the immediately preceding tests, check that gmr entry’s time_received value as shown in the following code, and ignore that gmr entry if too much time has passed since that gmr entry, in effect, last received a gravity message (note: the text between “/*” and “*/” are comments, not code):

/*
Note: This code is only concerned with gmr entries, and gmr entries are only for parents at level (n >= MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE).

Note: It is assumed that the internal clock of each computing element ticks at about the same rate.

Referring to paragraph p16, for a given level n, for n > 0, the gravity algorithm specifies a constant that is a time interval (denote as k) for that level n (assume that for the gravity algorithm, the time intervals are measured in clock ticks, and k is an integer that is a specific number of clock ticks). For level n, k is the wanted time interval between any two successively sent gravity-related messages by a parent at that level n.

Two reasons for the safety_factor in the below code:

  1. Note that the computing-element program is like an operating system and is assumed to be multitasking, and, even though one can assume that the gravity algorithm runs at a high priority, it is always possible that a specific parent at level n has one or more other high-priority tasks to do at the same time that it is supposed to be doing the work needed to prepare and send that next gravity-related message. Thus, even though the k value for level n is an exact and unchanging constant in the gravity algorithm, one can only assume that a given parent at level n will be sending a gravity-related message approximately every k clock ticks and not exactly every k clock ticks. Thus, k is an approximation, albeit probably a close approximation, of the time interval between two successively sent gravity-related messages by a given parent at level n.

  2. For a given gmr entry and its from_parent_XYZ value, even though the distance between this_CE’s XYZ coordinate and that parent’s from_parent_XYZ coordinate is fixed and unchanging, the most recently received gravity message in that gmr entry, was sent from the computing element at that gmr entry’s center_of_mass_XYZ coordinate (see paragraph p15), and this center_of_mass_XYZ coordinate, for that gmr entry, can change from one received gravity message to the next, which means that the message transit time for each of two successively received gravity messages for that gmr entry, can be different (this message transit time includes the transit time of the gravity-info message, if any, that resulted in that gravity message).

    Note: Reason 1 is why I chose a value of 2 for the below safety_factor. If instead, there was only reason 2 to consider, then a safety_factor of 1.01 would, I think, be more than enough.

The below code, which, in effect, ignores an “old” gravity message, is needed for the following reason: For a given gmr entry, which specifies a specific parent and level number, the most recently sent gravity message that originated from that parent at that level, won’t be received by this_CE if this_CE is not within range of that most recently sent gravity message, even though this_CE has received in the past, perhaps very recently, gravity messages that originated from that parent at that level (denote the most recently received gravity message from that parent at that level, whose center_of_mass_XYZ and total_mass values are currently in that gmr entry, as RR). This situation can happen because:

  1. The total_mass value in that most recently sent gravity message is now smaller (compared to RR) which reduces the send_distance for that most recently sent gravity message (see paragraph p15).

    OR

  2. The center_of_mass_XYZ coordinate in that most recently sent gravity message, which is the coordinate of the computing element from which that most recently sent gravity message was sent (see paragraph p15), is now further away (compared to RR) from this_CE.

    OR

  3. Both 1 and 2.

Thus, unless it is “aged” and, in effect, discarded when too old, the center_of_mass_XYZ and total_mass from an old gravity message—whose center_of_mass_XYZ and/or total_mass values are no longer correct when compared to the most recently sent gravity message that originated from that parent at that level—will remain in that gmr entry until the next gravity message is received from that parent at that level, which, in the worst case, can be very far in the future or never.
*/
set elapsed_time to ((the current time on this_CE’s internal clock) − (this gmr entry’s time_received))

set safety_factor to 2  /* See the above comments regarding this safety_factor. */

set clock_ticks_between_sends to (the gravity algorithm’s k value for this gmr entry’s level_num)  /* See the above comments regarding k. */

set allowed_elapsed_time_until_ignore to (safety_factor × clock_ticks_between_sends)

if elapsed_time > allowed_elapsed_time_until_ignore
then
Ignore this gmr entry. And also set its total_mass to zero so that this gmr entry will have to, in effect, receive another gravity message before this code can be executed again for this gmr entry.
end if

p21:: For each gmr entry not ignored (see paragraph p20): First use the distance formula to compute the distance d between this_CE’s XYZ coordinate and that gmr entry’s center_of_mass_XYZ coordinate. Then, use Newton’s formula for computing the force of gravity between two masses: set temp to (((the mass of the particle currently held by this_CE) × (that gmr entry’s total_mass value)) ÷ (d2)). Then compute that gmr entry’s gravitational force on this_CE’s held particle as being (temp × (a constant defined in the computing-element program for converting the temp value so that its unit of measurement is the force unit used within the computing-element program for those forces that can contribute to moving a nonzero-mass particle; see paragraphs p19 and p22)). The gravitational force vector representing that gmr entry’s gravitational force on the particle currently held by this_CE, begins at this_CE’s XYZ coordinate (this is the vector’s tail-point), and the vector’s length is that gmr entry’s above computed gravitational force, and this vector lies on the line that runs thru these two XYZ points: this_CE’s XYZ coordinate, and that gmr entry’s center_of_mass_XYZ coordinate (computing this vector’s head-point is detailed in paragraph p24). Then, after all these gravitational force vectors have been computed (as many as 1,269 gravitational force vectors, assuming each computing element has 1,269 gmr entries; see paragraph p17), these gravitational force vectors are added together to get a single total-gravitational-force vector that represents the net effect of all the above computed gmr gravitational force vectors on the particle currently held by this_CE.

p22:: After the total-gravitational-force vector is computed (see paragraph p21), that total-gravitational-force vector is added together with other currently applicable force vectors, if any, that can contribute to moving the nonzero-mass particle currently held by this_CE (a final composite force vector is the result of these added-together force vectors). As an example of possible force vectors added to the total-gravitational-force vector, there is probably a momentum force vector for that particle currently held by this_CE, and if that particle is a bion, there may still be an active force vector that resulted from one of that bion’s learned programs very recently calling the learned-program statement move_this_bion(). After this_CE has computed this final composite force vector for moving the particle that this_CE currently holds, this_CE uses this final composite force vector as input for the computing-element program’s algorithm for determining how long this_CE will hold the particle it is currently holding. This final composite force vector is also used, along with some history info (described in paragraph p23), as input into a different algorithm that determines which of this_CE’s six adjacent computing elements to copy that particle’s information block to when this_CE ends its current hold of that particle.

p23:: Regarding paragraph p22 and the “history info” mentioned: Assuming that this_CE is not at the edge of the universe, this_CE has six adjacent computing elements. The final composite force vector computed by this_CE (see paragraph p22) can be pointing in any direction, but there are only six directions in which to move the particle currently held by this_CE. Thus, a correction is needed so that, even though the particle will likely be moving in a very jagged path on the scale of the computing elements, on a larger scale that particle will be moving along the line or curve that the sequence of computed final composite force vectors would have that particle moving along. In addition to the final composite force vector computed by this_CE, also needed as input into the algorithm that decides which of this_CE’s six adjacent computing elements to move that held particle to, is a history of the final composite force vector computed by each of the most recent q computing elements that have held that particle, for some integer number q. Note that each final composite force vector in this history info has as its tail-point the XYZ coordinate of the computing element that computed that final composite force vector. After this history info—that this_CE got from the previous computing element that held the particle that this_CE is currently holding—is used by that algorithm, along with the final composite force vector computed by this_CE, to determine which of this_CE’s six adjacent computing elements to move that held particle to, this history info is then updated: The oldest final composite force vector in this history info is deleted, and the final composite force vector computed by this_CE is added. Then, when this_CE finally moves that particle to an adjacent computing element, this updated history info is also passed along with that particle to that adjacent computing element.

p24:: Regarding paragraph p21 and the gravitational force vector for a gmr entry that is not ignored (denote this gravitational force vector as vector V), vector V’s head-point is computed as follows: Vector V’s tail-point is this_CE’s XYZ coordinate (denote the X, Y, and Z components of this tail-point as x1, y1, and z1, respectively). Also, denote the X, Y, and Z components of the gmr entry’s center_of_mass_XYZ value as x2, y2, and z2, respectively. Note that vector V lies on the line that runs thru the two points (x1, y1, z1) and (x2, y2, z2). Also, the length of vector V (denote as L) was computed in paragraph p21, and this computed length L will always be greater than zero because of the assumption of no negative masses (see paragraph p11) and the conditions for ignoring gmr entries (see paragraph p20). Note that the unknown regarding vector V is its head-point (denote the X, Y, and Z components of vector V’s head-point as x3, y3, and z3, respectively). Thus, given point (x1, y1, z1) which is both this_CE’s XYZ coordinate and vector V’s tail-point, and given point (x2, y2, z2) which is the gmr entry’s center_of_mass_XYZ, and given L (the length of vector V), we need to compute the head-point (x3, y3, z3) of vector V. Note that the computed value of (x3, y3, z3) must satisfy two different equations. The first equation is the equation of a line when two different points on that line—in this case, (x1, y1, z1) and (x2, y2, z2)—are known: ((x3 − x1) ÷ (x2 − x1)) = ((y3 − y1) ÷ (y2 − y1)) = ((z3 − z1) ÷ (z2 − z1)). The other equation is the distance formula: L = square_root_of((x3 − x1)2 + (y3 − y1)2 + (z3 − z1)2). In June 2017, I used the latest version of a commercially available program (Mathematica) to solve this. In the below rules and formula, R identifies either x3, y3, or z3 as the value to be computed by the below formula:

  • The rules:

    • If R is x3, then: C is x1 and E is (x2 − x1). If x2 > x1, then add_or_subtract is + (add); otherwise, add_or_subtract is − (subtract).

      Note, when x2 equals x1, the operation in add_or_subtract (either add or subtract) doesn’t matter, because the square_root_of() value in the below formula will be zero because the value of E will be zero. This note also applies to the next rule if y2 equals y1, and the rule after that if z2 equals z1.

    • If R is y3, then: C is y1 and E is (y2 − y1). If y2 > y1, then add_or_subtract is + (add); otherwise, add_or_subtract is − (subtract).

    • If R is z3, then: C is z1 and E is (z2 − z1). If z2 > z1, then add_or_subtract is + (add); otherwise, add_or_subtract is − (subtract).

  • The formula:

    • R = ( C   add_or_subtract   square_root_of((L2 × E2) ÷ ((x2 − x1)2 + (y2 − y1)2 + (z2 − z1)2)))

p25:: For example, if L is 2.7 and (x1, y1, z1) is (2, 5, 7) and (x2, y2, z2) is (9, 3, 6), then (accurate to 5 decimal places) x3 is 4.57196, y3 is 4.26515, and z3 is 6.63258. Note: Confirming that the computed head-point (x3, y3, z3) was computed correctly can be done by plugging the computed x3, y3, and z3 values into the two equations given in paragraph p24 (the line equation and the distance formula). For the line equation, confirm that the equalities hold (if the denominator is zero—division by zero—for any of the three terms in the line equation that are supposed to be equal to each other, then ignore that term when checking that the equalities hold). For the distance formula, confirm that the computed distance is the L value. (I’ve already used Mathematica to compute many test cases and confirm that the above rules and formula for computing vector V’s head-point are flawless. I assume that the above rules and formula are nothing new, and they may already be on the internet somewhere, but my attempt to find them online was unsuccessful, so I had to do the work myself with Mathematica’s help, because I didn’t want to leave any part of this gravity algorithm unfinished.)

p26:: Regarding paragraphs p21 and p22, the fastest and lowest-computation-cost way to add together force vectors is the head-to-tail vector addition method (for a description of this method, see, for example, Vectors at https://www.mathsisfun.com/algebra/vectors.html). To show how this head-to-tail vector addition method would be done in the case of the force-vector additions done in paragraphs p21 and p22, first note that all these force vectors have the same tail-point which is this_CE’s XYZ coordinate, which is the XYZ coordinate of the particle that these force vectors will act upon. Next, because paragraph p21 has many more force vectors to be added together than paragraph p22, let’s assume that we have 1,269 gravitational force vectors to add together (see paragraph p21). The order in which the vectors are added together doesn’t matter, because the same final head-point XYZ is the result. Note: the word “translate” with regard to a vector means to move that vector without changing its orientation and length. To add a vector, translate that vector so that its tail-point XYZ is moved to the current head-point XYZ of the growing vector chain (denote the current vector to be added to the vector chain as vector G, and denote vector G’s tail-point and head-point as G_TAIL_XYZ and G_HEAD_XYZ, respectively; also denote the current head-point XYZ of the growing vector chain as VC_HEAD_XYZ, and note that the first VC_HEAD_XYZ value is the head-point XYZ of whichever of the 1,269 force vectors is chosen as the first link in the vector chain—the other 1,268 force vectors are then added in sequence to that vector chain). To add vector G to the current vector chain, using the head-to-tail vector addition method, first set diff_X to (VC_HEAD_XYZ.X − G_TAIL_XYZ.X), set diff_Y to (VC_HEAD_XYZ.Y − G_TAIL_XYZ.Y), and set diff_Z to (VC_HEAD_XYZ.Z − G_TAIL_XYZ.Z). Then, compute the new head-point XYZ of the vector chain: set VC_HEAD_XYZ.X to (G_HEAD_XYZ.X + diff_X), set VC_HEAD_XYZ.Y to (G_HEAD_XYZ.Y + diff_Y), and set VC_HEAD_XYZ.Z to (G_HEAD_XYZ.Z + diff_Z). Then, after all 1,269 gravitational force vectors are in the vector chain, the total-gravitational-force vector is the vector whose tail-point XYZ is the XYZ coordinate of this_CE, and its head-point XYZ is the final VC_HEAD_XYZ value of that vector chain, and the net amount of that vector chain’s gravitational force on the particle held by this_CE is the length of that total-gravitational-force vector, which is the distance, computed using the distance formula, between that total-gravitational-force vector’s tail-point XYZ and its head-point XYZ.

Detailed Code for computing Parents, a Parent’s Parent, and Surrounding Parents

p27:: Paragraphs p9 and p17 describe initializations for this gravity algorithm, done by each computing element shortly after that computing element came into existence. Paragraph p9 says:

Assume that shortly after each computing element came into existence, its computing-element program computed for that computing element (denote as this_CE) the levels, if any, at which this_CE is a parent (see paragraph p29 for the code to do this). And, for each level (n < 80) at which this_CE is a parent, also computed is the XYZ coordinate of that parent’s parent at level (n + 1) (see paragraph p30 for the code to compute a parent’s parent). … Also, if this_CE is not a parent at level 1, then save in this_CE’s state information the XYZ coordinate of this_CE’s parent at level 1 (see paragraph p29 for the code to do this), because this_CE will send a mass message to that parent at level 1 whenever the mass currently held by this_CE changes (see paragraph p10).

p28:: A cube has eight corner points. Assuming our universe is a giant cube of computing elements (see paragraph p3), our universe has eight corner points, and each of these eight corner points is a computing element that has an XYZ coordinate. To compute the XYZ coordinates of parents as needed by paragraphs p9 and p17, we have to know which of those eight corner points in our universe has the lowest X, Y, and Z values. I think there are only two reasonable choices for the lowest-coordinate corner point in our universe: either XYZ coordinate (0, 0, 0) or XYZ coordinate (1, 1, 1). My own preference, and it makes the following math a little simpler, is XYZ coordinate (0, 0, 0), and the following math assumes that (0, 0, 0) is the XYZ coordinate of the computing element at the lowest-coordinate corner point in our universe.

p29:: For the following math, (xyz) is the XYZ coordinate of this_CE. And, n is the level number, for levels 1 thru 80. The code for computing the XYZ coordinate of the parent at level n, of the cube at level n that inclusively contains the computing element this_CE whose XYZ coordinate is (xyz), follows:

/*
This code assumes that the computing element at the lowest-coordinate corner point in our universe has XYZ coordinate (0, 0, 0).

x, y, and z are the X, Y, and Z components, respectively, of this_CE’s XYZ coordinate.

A few examples should make clear how the math operator integer_part_of() works: integer_part_of(0) is 0, integer_part_of(3) is 3, integer_part_of(3.001) is 3, integer_part_of(3.999) is 3, integer_part_of(3.9999999999999999999999999) is 3. Note: I’m assuming that the computing-element program can do all the math operations in this code with sufficient precision so that every computing element in our universe will have its parent info computed correctly.

As an example of how the below code works, if the level number n is 2 and this_CE’s XYZ coordinate (xyz) is (23, 6, 17), then cube_side_width is 9 and the low-corner XYZ is (18, 0, 9) = (9 × 2, 9 × 0, 9 × 1) and the add_this is 4 and the parent XYZ is (22, 4, 13) and this_CE is not a parent at level 2.
*/
/*
Part 1 of this code:
*/
set cube_side_width to 3n  /* The width of a level n cube, measured in computing-element widths. */

set low_corner_X to (cube_side_width × integer_part_of(x ÷ cube_side_width))
set low_corner_Y to (cube_side_width × integer_part_of(y ÷ cube_side_width))
set low_corner_Z to (cube_side_width × integer_part_of(z ÷ cube_side_width))

set add_this to integer_part_of(cube_side_width ÷ 2)

set parent_X to low_corner_X + add_this
set parent_Y to low_corner_Y + add_this
set parent_Z to low_corner_Z + add_this

/*
Part 2 of this code:
*/
if x equals parent_X
and y equals parent_Y
and z equals parent_Z
then
this_CE is a parent at level n
else
this_CE is not a parent at level n
if n is 1  /* this_CE, which is not a parent at level 1, needs to know where to send its mass messages. */
then
Save in this_CE’s state information the XYZ coordinate of this_CE’s parent at level 1, which is the XYZ coordinate (parent_Xparent_Yparent_Z).
end if
end if

p30:: When this_CE is a parent at level n, and n is less than the assumed maximum level number which is 80, to compute the XYZ coordinate of that parent’s parent at level (n + 1), just add 1 to n and compute Part 1 in the above code: the resulting XYZ coordinate (parent_Xparent_Yparent_Z) is the XYZ coordinate of that parent’s parent.

p31:: Paragraph p17 says:

Assume that shortly after each computing element came into existence, its computing-element program computed for that computing element (denote as this_CE) the XYZ coordinates of the originating parents from which this_CE will accept gravity messages. More specifically, compute at each level n, for levels MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE thru 80 inclusive, the XYZ coordinate of the parent for the level n cube that contains this_CE, and the XYZ coordinates of the 26 parents for the level n cubes that immediately surround the level n cube that contains this_CE (to make clear what is meant by “immediately surround”, these 27 cubes together have the shape of a cube; see paragraph p32 for the code to compute the XYZ coordinates of these 27 parents at level n).

p32:: The XYZ coordinate of the parent for the level n cube that contains this_CE is computed by Part 1 in the above code, and this parent’s XYZ coordinate is (parent_Xparent_Yparent_Z). The XYZ coordinates of the other 26 parents at level n, that “immediately surround” (parent_Xparent_Yparent_Z), are:

set m to 3n  /* The width of a level n cube, measured in computing-element widths. */

/*
The XYZ coordinates of the other 26 parents at level n, that “immediately surround” (parent_Xparent_Yparent_Z), are:
*/
(parent_X + mparent_Yparent_Z)
(parent_X − mparent_Yparent_Z)
(parent_Xparent_Y + mparent_Z)
(parent_Xparent_Y − mparent_Z)
(parent_Xparent_Yparent_Z + m)
(parent_Xparent_Yparent_Z − m)

(parent_X + mparent_Y + mparent_Z)
(parent_X + mparent_Y − mparent_Z)
(parent_X − mparent_Y + mparent_Z)
(parent_X − mparent_Y − mparent_Z)

(parent_X + mparent_Yparent_Z + m)
(parent_X + mparent_Yparent_Z − m)
(parent_X − mparent_Yparent_Z + m)
(parent_X − mparent_Yparent_Z − m)

(parent_Xparent_Y + mparent_Z + m)
(parent_Xparent_Y + mparent_Z − m)
(parent_Xparent_Y − mparent_Z + m)
(parent_Xparent_Y − mparent_Z − m)

(parent_X + mparent_Y + mparent_Z + m)
(parent_X + mparent_Y + mparent_Z − m)
(parent_X + mparent_Y − mparent_Z + m)
(parent_X + mparent_Y − mparent_Z − m)
(parent_X − mparent_Y + mparent_Z + m)
(parent_X − mparent_Y + mparent_Z − m)
(parent_X − mparent_Y − mparent_Z + m)
(parent_X − mparent_Y − mparent_Z − m)

p33:: Regarding edge cases, if any of the above computed XYZ coordinates of the other 26 parents at level n are outside our universe, then it’s still okay for this_CE to have a gmr entry for that parent’s XYZ coordinate at that level n, because that gmr entry’s total_mass is initialized to null when that gmr entry was made (see paragraph p17), and there will never be a received gravity message from that XYZ coordinate because it’s not in our universe, which means that that gmr entry’s total_mass will always be null and that gmr entry will always be ignored (see paragraph p20). Note: Assuming that the computing element at the lowest-coordinate corner point in our universe has XYZ coordinate (0, 0, 0), then any XYZ coordinate whose X, Y, or Z component is negative, is outside our universe. However, I’m not making any assumption that the gravity algorithm or any other part of the computing-element program knows and uses the XYZ coordinate of the highest-coordinate corner point in our universe, because such knowledge simply isn’t needed.

Regarding the above Gravity Algorithm: Approximations and Efficiency

The above gravity algorithm has two separate approximations that make the computed gravitational force on the particle currently held by this_CE an approximation. The first approximation happens in the part of the algorithm where each cube at level (n > 0) adds up the mass in the 27 cubes at level (n − 1) that compose that level n cube, and computes a single center-of-mass XYZ coordinate for that sum of masses. Newton’s formula for computing the force of gravity between two masses, assumes that the two masses are point masses, but only the mass of the particle held by this_CE (denote this mass as M1) is a point mass. The other mass (denote this mass as M2) is a mass that’s a sum of 27 individual masses, with a computed center-of-mass XYZ coordinate for that sum of 27 individual masses. In this case, the computed gravitational force vector between masses M1 and M2 will most likely be an approximation compared to the more accurate result that would be gotten by computing a separate gravitational force vector between M1 and each of the 27 separate masses at their original XYZ coordinates, and then adding together those 27 gravitational force vectors into a single gravitational force vector as the gravitational force between masses M1 and all of the 27 masses that were combined into mass M2. Although just an approximation, combining masses into a single mass at a single center-of-mass XYZ coordinate is a requirement for any efficient gravity algorithm within the computing-element reality model, because the alternative is to compute at each computing element holding a nonzero-mass particle, as many gravitational force vectors as there are nonzero-mass particles within whatever range one gives to the force of gravity. Given that our Earth alone has an estimated 1050 atoms (How many atoms are there in the world? at http://education.jlab.org/qa/mathatom_05.html), the necessity of combining masses—before computing the gravitational force vectors acting on the particle currently held by this_CE—should be obvious.

The other approximation in the above gravity algorithm is that the parent of a level n cube, for n > MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE, adds up the mass in each of its 27 level (n − 1) cubes that that level n cube contains, and computes the center-of-mass XYZ coordinate for that added-up mass, and then sends a gravity-related message for that level n cube reporting that added-up mass and its center-of-mass XYZ coordinate. However, for each of that level n cube’s 27 level (n − 1) cubes, its parent has also sent a gravity-related message for that level (n − 1) cube’s share of that added-up mass that its enclosing level n cube will also send a gravity-related message for. Thus, assuming 80 is the maximum level number—and ignoring time delays regarding message transmission, and the periodic wait by a level n parent before it sends a gravity-related message for that level—the mass of a single particle will be included in the total_mass of ((80 − MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE) + 1) different gravity messages, each at a different level (if MIN_LVL_FOR_SENDING_A_GRAVITY_MESSAGE is 34, then 47 different gravity messages). (Perhaps this multiple counting of mass by the above gravity algorithm explains the so-called “missing mass” that astrophysicists say our galaxy has. However, this is just a suggestion, because I haven’t done any math or other work to support this suggestion, nor have I spent substantial time studying this “missing mass” subject and its justification.)

Regarding the above two approximations, I don’t think any physical experiment can be done on a small scale here on our Earth that would be able to reveal that the gravitational force vector that applies to an elementary particle of nonzero mass (denote this particle as particle X), is being imperfectly computed by the underlying reality. The reason I say this is because it is impossible to, in effect, freeze time and stop all motion, and then precisely determine the mass and relative location in 3D space (relative to particle X) of every particle that is within gravitational range of that particle X, and then compute the gravitational force vector between each of those particles and particle X, and then add up all those computed gravitational force vectors to get the total-gravitational-force vector, and then compare this perfect total-gravitational-force vector with the exactly measured actual gravitational force that is acting on particle X. Also, any attempt to detect by physical experiment the existence of the cubes defined by the above gravity algorithm, is impractical for multiple reasons, including the fact that our solar system is moving thru 3D space, and thus moving thru the computing elements, at roughly 1/245th of lightspeed which is more than a million meters per second (see the footnote in subsection 3.8.6), which means that any physical experiment would be moving thru the smaller cubes at a very fast rate.

Regarding the efficiency of the above gravity algorithm, for those familiar with time complexity for an algorithm (see, for example, Time complexity at https://en.wikipedia.org/wiki/Time_complexity), all the operations done in the above gravity algorithm have constant-time cost, and some of the multiplying constants involved with those operations are small, such as 80 levels (see paragraph p2), each parent having 27 children (see paragraphs p6 and p7), and at most 1,269 gravitational force vectors—one for each non-ignored gmr entry—computed by a computing element after that computing element begins holding a particle with a nonzero mass (see paragraph p21). The only large multiplying constants for a computing element are the number of messages being sent and/or received by that computing element regarding the gravity algorithm. In the case of mass messages, assuming there is a lot of nonzero-mass particles moving thru a level 1 cube in a short period of time, such as when our Earth is passing thru a level 1 cube, there could easily be a large number of mass messages sent per second, to that level 1 cube’s parent. However, mass messages are simple, and have a low constant-time cost to prepare and send a mass message (see paragraphs p10 and p12), and a low constant-time cost to receive and process a mass message (see paragraph p12). In the case of gravity-related messages sent by a parent at the lowest level number that can send gravity-related messages, my guess is that billions of gravity-related messages per second are sent by that parent. However, computing the center_of_mass_XYZ and total_mass for 27 children is a simple operation with a low constant-time cost (see paragraph p12), and then preparing and sending a gravity-related message is also a simple operation with a low constant-time cost (see paragraph p15). In the case of a computing element receiving gravity messages, my guess is that a computing element currently within our Earth is receiving at least billions of gravity messages per second (recall that the range of a gravity message is dependent on the total_mass value in that gravity message, which is why I specifically said “a computing element currently within our Earth”, because a computing element currently far out in empty space would be receiving a much smaller number of gravity messages per second). However, receiving and processing a gravity message (see paragraph p18) is a simple operation with a low constant-time cost.

Assuming that the computing elements are computing at many, many orders of magnitude faster than our fastest physical computers, it follows that billions of simple messages per second, with a low constant-time cost for each message to either prepare and send that message or receive and process that message, is not a significant burden on a computing element, even if instead of billions of messages per second, the number of these messages per second is actually several orders of magnitude higher (such as trillions per second instead of billions per second). I think it likely that each computing element in our universe uses, per second, less than 1% of its computing power on behalf of the above gravity algorithm, even for the computing elements that have the most gravity-related work to do, which is each computing element at the exact center of a level 80 cube, assuming 80 is the maximum level number (the computing element at the exact center of a level 80 cube is a parent at levels 1 thru 80 inclusive). Note: a parent at level (n > 1) is also a parent at each lower level, all the way down to level 1, but I didn’t mention this detail in the above gravity algorithm because an explicit statement about it wasn’t needed (this detail is a consequence of how a parent and the cube hierarchy are defined in the above gravity algorithm).


3.8.4 The Learned-Program send() Statement: the message_instance

The message_instance is copied by the message-transmission algorithm from a computing element to adjacent computing elements, and so on, to send the message out into 3D space in search of the intended recipient(s) of that message. The following parameters of the send() statement are included in its sent message_instance:

  • The data being sent to the recipient(s), which is often referred to in this book as the “message text”.

  • The within-the-mind-or-not parameter if it was given.

  • The list_of_bions or the user_settable_identifiers_block, whichever was given as the parameter to identify the intended recipient(s) of the message, if the intended recipient(s) are one or more bions.

The message_instance also includes the following six items (these six items are always a part of any message_instance, regardless of whether that message_instance was put together within the send() statement’s routine or within some other routine):

  • The sender’s_XYZ is the XYZ coordinate of the computing element from which the message originated. Before copying this message_instance to its adjacent computing elements, the originating computing element sets sender’s_XYZ to this_CE’s_XYZ.

  • The sender’s_identifier_block identifies the sender of the message if that sender, in effect, is an intelligent particle (either a bion or a soliton):

    • If the message to be sent is being sent either directly by an intelligent particle (in general, this includes any messages sent by executing a learned-program statement from within an executing learned program—only intelligent particles have learned programs), or indirectly on behalf of an intelligent particle (an example is the LOCATION_REPLY_FROM_BION message sent by a computing element’s computing-element program reporting the location in 3D space of the bion currently held by that computing element), then sender’s_identifier_block is set to the identifier block of that intelligent particle (subsection 3.8.1 defines the identifier block of an intelligent particle).

    • If instead the message to be sent is not being sent by or on behalf of an intelligent particle, then sender’s_identifier_block is set to null. For example, when a computing element sends a message to a bion in reply to a request message from that bion regarding a common particle currently held by that computing element, that reply’s message_instance has its sender’s_identifier_block set to null, and any details about that common particle in that reply will be in the message text of that reply.

  • The instance_identifier has a default value of null, unless it is set by the sender.

  • The special_handling_locate and special_handling_non_locate are a pair of integer variables. In the context of these two variables, the special handling done is that at each intended recipient of that message, that message is handled directly by the computing-element program, and not by any learned programs of that intelligent particle if that intended recipient is an intelligent particle. Also, if that intended recipient is an intelligent particle, that message is not placed in that intelligent particle’s message queue.

    For any direct call of the send() statement by a learned program, both special_handling_locate and special_handling_non_locate are set to null. If the message to be sent is not being sent by a direct call of the send() statement by a learned program, and the above special handling is the case for that message, then:

    • If that message is a location message—either that message is requesting location info or is replying to a location request with location info—then special_handling_locate is set to a value that identifies that message (for example, the two identifiers GET_LOCATIONS_OF_BIONS and LOCATION_REPLY_FROM_BION). Assume that any setting of special_handling_locate to a non-null value also sets special_handling_non_locate to null.

    • If that message is not a location message then special_handling_non_locate is set to a value that identifies that message (for example, the identifier MOVE_PHYSICAL_ATOM). Assume that any setting of special_handling_non_locate to a non-null value also sets special_handling_locate to null.

  • The integer transfer_count is always initialized to zero whenever a message_instance is put together. This transfer_count is the only part of a message_instance that changes as that message_instance, in effect, moves thru 3D space. If special_handling_locate is not null, then this transfer_count will be involved with computing the relative location of a particle (see how the transfer_count is used in the reply_to_this_location_request_bions() and process_a_location_reply_from_a_bion() routines in subsection 3.8.6).

  • The integer send_distance limits how far a message_instance can travel in 3D space, and this send_distance is initialized as follows:

    In the case of a direct call of the send() statement by a learned program: if the message is being sent to or from a soliton, or the message is being sent within the mind as per the within-the-mind-or-not parameter, then send_distance is set to a small multiple of SOLITON_AND_ITS_OWNED_BIONS_MAX_SEPARATION_DISTANCE; otherwise, send_distance is set to the edited value of the send() statement’s use_this_send_distance parameter whose maximum allowed value is MAX_SEND_DISTANCE_ALLOWED_FOR_SEND_STATEMENT.

    In the preceding paragraph, the reason for the “small multiple” is to allow for the possibility that as a soliton and its owned bions move thru 3D space, the maximum separation distance allowed between any two of these particles, which is SOLITON_AND_ITS_OWNED_BIONS_MAX_SEPARATION_DISTANCE, may occasionally be slightly exceeded. Another reason is the absolute motion of our world thru 3D space and its effect (in our world probably a very small effect) on the total distance a sent message must travel, relative to the sender’s_XYZ, to reach its intended recipient(s). A small multiple of 1.1 is probably completely safe as being more than enough to guarantee that the sent message will reach its intended recipient(s).

    In cases other than a direct call of the send() statement by a learned program, the send_distance is initialized as shown or implied by the code and/or discussion for other learned-program statements and/or routines that follow further below in this book. Note that in general, a message that is sent as a reply to some message that was received, can simply use as that reply’s send_distance the same send_distance value that was used for that received message. An example of this is shown in the detail of the reply_to_this_location_request_bions() routine in subsection 3.8.6. Note that if that received message instance was very close to its send_distance limit when received, then the sent reply message, using that same send_distance value as that received message, may not be received by the bion that sent the message that resulted in that reply. However, if this is the case, then it doesn’t matter if the bion sending the reply has its sent reply message received or not, because that replying bion was almost out of range to begin with.

3.8.5 The Learned-Program send() Statement: Algorithmic Details

Regarding how I’ve coded the routines in this book: A comment helps explain the code, and begins with “/*” and ends with “*/”. I’ve borrowed various keywords from other programming languages and these borrowed keywords are boldface, and also boldface are a few other commands in the code, such as those regarding semaphores. In the code, the names of variables are italicized (elsewhere, outside of the code, including in comments, the names of variables and routines are both italicized, but the names of routines are always suffixed with “()” to distinguish them from variables). A named constant consists of two or more words separated by underscores, and all letters in the words are capitalized. The variable this_CE in the code is the computing element that is currently executing the routine, and this_bion in the code is the bion that is executing the routine. An if can be nested inside another if, in which case the end if always ends the nearest un-ended preceding if. Many programming languages use what is known as “dot notation” to show that the variable name that is suffixed after the dot is contained in the data structure whose variable name is prefixed before that dot. For example, message_instance.transfer_count refers to the value of a variable named transfer_count that is contained in the data structure named message_instance.

The computing-element program is like an operating system and is assumed to be multitasking, and can have different threads of execution ongoing at the same time. And each thread of execution will have a priority: the higher its priority compared to whatever other threads of execution are currently ongoing, the bigger its time slice compared to the time slices for those other threads of execution that are currently ongoing (a thread’s time slice is how long that thread can run (execute) before its execution is paused by the operating system so that one or more other ongoing threads can run; this explanation of multitasking assumes that the computing element is, in effect, a uniprocessor, and can only be executing one thread at any instant of time).

In general, regarding the speed of message transmission thru 3D space, it is reasonable to assume that message transmission has at least as high a priority in the computing-element program as the priority for moving a photon thru 3D space (photons move at or near lightspeed). Assuming an average-sized message, one can assume that that message will, in effect, from whichever computing element the intelligent particle was in when its message was sent by the send() statement, radiate outward, filling a sphere of radius send_distance, at a speed that’s at least as fast as lightspeed, and probably much, much faster than lightspeed (see chapter 1 regarding instantaneous communication, and the speed of gravity). Because of its importance and its need to be fast, message transmission has a very high priority.

Within the send() statement, after the message_instance has been constructed, the next step copies that message_instance to each computing element that is adjacent to the computing element that the sender, an intelligent particle, is currently occupying during this step in the processing of that send() statement (assume that during this step the computing-element program will not move that sender out of its currently occupied computing element). As soon as at least one of these adjacent computing elements has that message_instance, that is the point at which the message-transmission algorithm presented in this subsection becomes involved with that message_instance.

Handling the Special Case of a Recipient Particle being Moved when the Message Arrives

For the message-transmission algorithm presented in this subsection, a message_instance is copied from computing elements that currently have the message_instance to certain adjacent computing elements, until every computing element within message_instance.send_distance of the message_instance.sender’s_XYZ has received that message_instance (filling a sphere-shaped volume of 3D space—but it’s not a math-perfect sphere because the computing elements that compose 3D space have a finite cube size). However, this copying process takes finite time, and during this finite time to fill that sphere, it is possible that some particle X that is a recipient of that message_instance, is in the process of being moved from one computing element to an adjacent computing element when that message_instance is, in effect, being transmitted thru one or both of those two computing elements.

The code in examine_a_message_instance() covers this possibility, so that recipient particle X won’t miss receiving that message_instance even though particle X is currently being moved from one computing element to an adjacent computing element when that message_instance arrives. To support this, assume that the state information of each computing element (denote as this_CE) includes a variable named held_particle_status which always has a value, and there are four different values: NOT_CURRENTLY_HOLDING_A_PARTICLE, CURRENTLY_HOLDING_A_PARTICLE, CURRENTLY_MOVING_HELD_PARTICLE_TO_AN_ADJACENT_CE, and CURRENTLY_RECEIVING_A_PARTICLE_FROM_AN_ADJACENT_CE:

  • NOT_CURRENTLY_HOLDING_A_PARTICLE : this_CE is not currently holding a particle.

  • CURRENTLY_HOLDING_A_PARTICLE : this_CE is currently holding a particle.

  • If this_CE’s held_particle_status is CURRENTLY_HOLDING_A_PARTICLE, and this_CE has, in effect, gotten agreement from an adjacent computing element (denote as move_to_CE) that this_CE will move its held particle to move_to_CE, then as soon as that agreement is reached, two things happen:

    • this_CE sets its messages_for_particle_being_moved list to empty if it is not already empty, and this_CE changes its held_particle_status to CURRENTLY_MOVING_HELD_PARTICLE_TO_AN_ADJACENT_CE.

      Note: Any message_instance received by this_CE while this_CE’s held_particle_status is CURRENTLY_MOVING_HELD_PARTICLE_TO_AN_ADJACENT_CE, is examined and if the particle being moved is either a recipient of that message_instance or can be affected by that message_instance, then save that message_instance into this_CE’s messages_for_particle_being_moved list (see the code regarding this in examine_a_message_instance()).

    • move_to_CE sets its messages_for_particle_being_moved list to empty if it is not already empty, and move_to_CE changes its held_particle_status to CURRENTLY_RECEIVING_A_PARTICLE_FROM_AN_ADJACENT_CE.

      Assume that before that agreement is reached, this_CE has already given to move_to_CE the identifying information, if any, of the particle that this_CE is currently holding. For a held intelligent particle (either a soliton or a bion) that identifying information would be that intelligent particle’s identifier block. For a physical atom, that identifying information would be that atom’s unique identifier (see subsection 3.8.8).

      The purpose of move_to_CE having this identifying information of the particle it will receive, is so that any message_instance received by move_to_CE while move_to_CE’s held_particle_status is CURRENTLY_RECEIVING_A_PARTICLE_FROM_AN_ADJACENT_CE, can be examined and saved into move_to_CE’s messages_for_particle_being_moved list if that particle is either a recipient of that message_instance or can be affected by that message_instance (see the code regarding this in examine_a_message_instance()).

    After CURRENTLY_MOVING_HELD_PARTICLE_TO_AN_ADJACENT_CE and CURRENTLY_RECEIVING_A_PARTICLE_FROM_AN_ADJACENT_CE have been set, the move-a-particle process includes the following steps (this process will execute with a high priority on both this_CE and move_to_CE):

    1. If the particle is an intelligent particle (either a bion or a soliton), any learned programs of that particle that are currently running are halted (their execution is stopped), and their executions will be resumed shortly after that particle has been moved to move_to_CE.

      In general, there will be no interactions of the particle with other particles in its environment until after the move process has completed.

    2. The particle’s information block is copied from this_CE to move_to_CE.

    3. this_CE copies to move_to_CE additional information that is relevant to the particle being moved. This copying includes this_CE’s “updated history info” described in paragraph p23 in footnote 23. Also copied to move_to_CE is this_CE’s messages_for_particle_being_moved list, which may be empty.

      After this_CE completes this step, it changes its held_particle_status to NOT_CURRENTLY_HOLDING_A_PARTICLE.

    4. At this point, move_to_CE has the particle’s information block and additional relevant info from this_CE regarding that particle.

      move_to_CE changes its held_particle_status to CURRENTLY_HOLDING_A_PARTICLE.

    5. move_to_CE compares its messages_for_particle_being_moved list with the messages_for_particle_being_moved list that it got from this_CE, and, in effect, merges the two lists together into a single list, removing any duplicate message_instances (if the only difference between two message_instances is the message_instance.transfer_count value, then each of those two message_instances is, in this context, a duplicate of the other, and one of them is discarded from the merged list).

      move_to_CE will then call examine_a_message_instance() for each message_instance in this merged-together list.

The Sphere-Filling Message-Transmission Algorithm

As was stated in subsection 3.8.3, each computing element is a cube with six sides, and, because our galaxy is apparently far away from any edge of our universe where there are no adjacent computing elements on one side, the code further below in pass_this_message_along() ignores edge cases and assumes that each computing element has six adjacent computing elements. However, one can assume that the complete code in the computing-element program, in effect, handles these edge cases.

For this message-transmission algorithm, whenever a computing element (denote as this_CE) receives (has copied to it) a message_instance from an adjacent computing element, this_CE does the following three steps:

  1. The first thing that this_CE does with the message_instance is increment message_instance.transfer_count by adding 1 to it. Note: this is the only change to the message_instance that this_CE will make.

  2. Then, this_CE starts two different threads of execution:

    • This first thread has a very high priority, and calls pass_this_message_along() with a reference to message_instance as the only parameter of this call (by “reference” is meant a pointer to the message_instance in this_CE’s memory).

      pass_this_message_along() does the actual sphere-filling message transmission of the message_instance.

    • This second thread has a high priority, but lower than the priority of the first thread above, because it is more important for the message_instance to be passed along to other computing elements than it is for this_CE to finish processing the message_instance.

      This second thread calls examine_a_message_instance() with a reference to message_instance as the only parameter of this call.

      With the exception of received gravity messages which are always processed by this_CE, examine_a_message_instance() determines the relevance, if any, that the received message (the message_instance) has with regard to whatever particle, if any, that this_CE is either currently holding or is in the process of moving or receiving, and takes appropriate action based on that relevance or lack of relevance.

  3. When both of the threads started by step 2 have completed, then the message_instance is deleted from this_CE’s memory.

Code for the two routines, examine_a_message_instance() and pass_this_message_along(), follows. The examine_a_message_instance() routine is given first:

examine_a_message_instance(message_instance)
{
if this message is a gravity message
then
Process this gravity message as described in paragraph p18 in footnote 23.
return  /* exit this routine */
end if

if held_particle_status is NOT_CURRENTLY_HOLDING_A_PARTICLE
then
return  /* exit this routine */
end if

/*
Note: when held_particle_status is CURRENTLY_RECEIVING_A_PARTICLE_FROM_AN_ADJACENT_CE, then that means that this_CE, which is calling this examine_a_message_instance(), is the move_to_CE described above.
*/
if held_particle_status is CURRENTLY_MOVING_HELD_PARTICLE_TO_AN_ADJACENT_CE
or held_particle_status is CURRENTLY_RECEIVING_A_PARTICLE_FROM_AN_ADJACENT_CE
then
/*
An example of a particle that is not a recipient of the message but can be affected by that message, is a physical atom and the message_instance.special_handling_non_locate is PUSH_PHYSICAL_MATTER (see subsection 3.8.8).
*/
Examine the message_instance and determine if the particle that is being moved is either a recipient of the message or can be affected by the message. If either is true, then copy the message_instance
to this_CE’s messages_for_particle_being_moved list.
return  /* exit this routine */
end if

/*
The held_particle_status is CURRENTLY_HOLDING_A_PARTICLE.
*/
if message_instance.special_handling_locate is null
and message_instance.special_handling_non_locate is null
and this_CE is currently holding an intelligent particle that is not asleep
and that intelligent particle qualifies as a recipient of the message  /* Examine the message_instance and also that intelligent particle’s identifier block to determine this. */
then
if that intelligent particle’s message queue is currently full  /* no room left in that message queue */
then
Delete the oldest message in that message queue.
end if
From the message_instance, add to that intelligent particle’s message queue an entry with the following components: the message text; the sender’s_identifier_block; and, if this intelligent particle is a bion, then include the sender’s selection criteria for determining the recipient(s) of this message (either the user_settable_identifiers_block parameter or the list_of_bions parameter, if either was given by the sender to identify the recipient(s) of this message); a distance value named distance_between_sender_and_receiver, which is the distance between message_instance.sender’s_XYZ and this_CE’s_XYZ (computed using the distance formula).
return  /* exit this routine */
end if

if message_instance.special_handling_locate is null
and message_instance.special_handling_non_locate is null
and this_CE is holding a common particle
and that common particle is a recipient of the message
/*
I haven’t defined in this book any messages that, in effect, end up here, but the computing-element program in its code for interacting common particles with each other may send messages that would end up here, in which case one can assume that that code, or a call to that code, for handling such messages would be here.
*/
return  /* exit this routine */
end if

if message_instance.special_handling_locate is null
and message_instance.special_handling_non_locate is null
then
return  /* exit this routine */
end if

/*
Handle the “special handling” messages.
*/
if (message_instance.special_handling_locate is either GET_LOCATIONS_OF_BIONS or LOCATION_REPLY_FROM_BION)
and this_CE is currently holding a bion that is not asleep
and that bion qualifies as a recipient of the message  /* Examine the message_instance and also that bion’s identifier block to determine this. */
then
if message_instance.special_handling_locate is LOCATION_REPLY_FROM_BION
then
process_a_location_reply_from_a_bion(message_instance)  /* this routine is detailed in subsection 3.8.6 */
else
reply_to_this_location_request_bions(message_instance)  /* this routine is detailed in subsection 3.8.6 */
end if
return  /* exit this routine */
end if

/*
The code to be added to this examine_a_message_instance() routine, that is given in subsections 3.8.8 Bions Seeing and Manipulating Atoms and Molecules, 5.2.1 Out-of-Body Movement during a Lucid Dream, and 5.2.3 How One’s Projected Bion-Body Maintains its Human Shape, goes here.
*/

return  /* exit this routine */
}

Code for the pass_this_message_along() routine follows:

/*
Determine which adjacent computing elements, if any, to copy the message_instance to.
*/
pass_this_message_along(message_instance)
{
set give_to_list to an empty list

/* (sxsysz) is the sender’s XYZ coordinate. */
set sx to message_instance.sender’s_XYZ.X
set sy to message_instance.sender’s_XYZ.Y
set sz to message_instance.sender’s_XYZ.Z

/* (cxcycz) is this_CE’s XYZ coordinate. */
set cx to this_CE’s_XYZ.X
set cy to this_CE’s_XYZ.Y
set cz to this_CE’s_XYZ.Z

/*
Referring to the three set statements after this comment, what is the fastest way to set random_bit_1, random_bit_2, and random_bit_3?

If one assumes that the computing elements encode integer values in binary (the same encoding used by our physical computers), then from a single random number composed of at least 3 bits, the three low-order bits can be extracted and each of those three bits assigned to random_bit_1, random_bit_2, and random_bit_3, respectively.

Because of how random_bit_1, random_bit_2, and random_bit_3 are used in this routine, and the purpose that they serve (see the explanation of the M_determine_which_of_these_two_ifs_executes() macro that is further below), as long as the probability is even-chance (aka 50-50 or 1-in-2 or 0.5 or ½) that the value of random_bit_1 in this routine for this message_instance for this_CE will be the same value for random_bit_1 in this routine for this message_instance when this message_instance is processed by a computing element that is adjacent to this_CE, then that will serve the intended purpose of random_bit_1 (and likewise this same even-chance requirement for random_bit_2 and random_bit_3).

A likely good source for setting random_bit_1, random_bit_2, and random_bit_3, that will give the even-chance probability explained in the previous paragraph, is to use the three low-order bits of this_CE’s internal clock to set random_bit_1, random_bit_2, and random_bit_3, respectively. Note that the three low-order bits would be the three fastest-changing bits as clock ticks are counted by that internal clock.
*/
In effect, set random_bit_1 randomly to either 0 or 1.
In effect, set random_bit_2 randomly to either 0 or 1.
In effect, set random_bit_3 randomly to either 0 or 1.

/*
In the below selection code, “M_append(an XYZ coordinate)” is a macro that represents code that does the following: If the distance (computed using the distance formula) between the given XYZ coordinate and the message_instance.sender’s_XYZ is not greater than message_instance.send_distance, then append that given XYZ coordinate to the give_to_list.

Note that the XYZ coordinate given to M_append() in the below selection code will always be the XYZ coordinate of a computing element that is adjacent to this_CE, assuming that this_CE has six adjacent computing elements. The six adjacent computing elements are: (cx + 1, cycz), (cx − 1, cycz), (cxcy + 1, cz), (cxcy − 1, cz), (cxcycz + 1), (cxcycz − 1).

Also, note that in the above description of macro M_append(), and also in the below selection code, I am ignoring edge cases for which this_CE is at an edge in our universe and as a result has less than six adjacent computing elements. However, one can assume that the computing-element program and its computing element, one way or another, handles these edge cases correctly.
*/
/*
This comment describes and explains the macro M_determine_which_of_these_two_ifs_executes(), which appears in three places in the below selection code. The only purpose of this macro is to make equal, for each of the three axes, X, Y, and Z, the average time needed for a message of size s to go from sender to receiver along an axis, regardless of whether the message is moving along that axis in a direction that increases that axis value or decreases that axis value. Making this average transfer time the same in both directions along an axis, eliminates directional bias, and doing this is only important in the case of those learned-program statements, such as get_relative_locations_of_bions(), that determine the relative locations of particles.

In the case of learned-program statements that determine the relative locations of particles, a message of size s is sent that results in reply messages that each have size s. In general, whatever direction the sent message had to move along the three axes, X, Y, and Z, to reach a replying particle, that particle’s reply message, to reach that sender, will have to move in the opposite direction along each of those three axes to reach that sender. The computation of relative locations, detailed in the code of process_a_location_reply_from_a_bion() in subsection 3.8.6, implicitly assumes the same average time to move a message_instance of size s in either direction along each of the three axes.

Regarding the message-transmission code in this routine: Along an axis, there are two directions in which to move, and this direction depends on the result of an expression that compares this_CE’s axis coordinate to the sender’s axis coordinate. Thus, there is an if-then-else statement involved: If the expression is true then move in one direction along that axis, else move in the opposite direction along that axis. The fundamental difficulty in preventing a directional bias is this if-then-else statement and its execution time. Assume that this if-then-else statement is coded in machine code that will execute as fast as possible (by “machine code” is meant the actual code that will execute on a computing element). And note that the execution time for moving in one direction along that axis (denote as A), and the execution time for moving in the opposite direction along that axis (denote as B), are exactly the same. However, the total execution time for executing this if-then-else statement will presumably be different depending on whether A or B is done:

if (v1 > v2)
then
A
else
B
end if

To understand why there is this difference in total execution time depending on whether A or B is done, even though A and B each take the exact same amount of execution time, the following is a description of what the machine code will be doing, assuming that the machine code of a computing element works the same way that our physical-computer machine code works, which means that the machine code is stored sequentially in addressable memory, and there is a memory pointer that points at the current location in memory where the next machine-code instruction to be executed is at:

1) Compare the value of v1 to the value of v2.

2) If the comparison result is not greater than—in other words, v1 not > v2—then advance the memory pointer that points at the next machine instruction to execute, to point at the beginning of the machine code that executes B.

3) The machine code that executes A is here.

4) Advance the memory pointer that points at the next machine instruction to execute, to skip over the machine code that executes B.

5) The machine code that executes B is here.

The presumption here, and the reason for the M_determine_which_of_these_two_ifs_executes() macro, is that the two different execution pathways thru the above if-then-else statement (one pathway executes A, and the other pathway executes B), have different execution times (let etd denote the absolute value of the difference between the following two execution times):

  • The execution time needed by the pathway that executes A is : ((the time needed to execute step 2 when the jump to the beginning of the machine code that executes B is not done) + (the time needed to execute step 4))

  • The execution time needed by the pathway that executes B is : (the time needed to execute step 2 when the jump to the beginning of the machine code that executes B is done)

If the above presumption is wrong in the case of the computing elements, which means that the value of etd is zero, then there is no need for the M_determine_which_of_these_two_ifs_executes() macro. In this case, one could just replace each occurrence of this macro in the below selection code with the first (or second) if-then-else statement given as a parameter to that macro. However, if etd is nonzero, then the presumption is that the pathway that executes A takes etd more time than the pathway that executes B.

To make clear how macro M_determine_which_of_these_two_ifs_executes() works, the following is the first occurrence of this macro in the below selection code:

M_determine_which_of_these_two_ifs_executes(
    random_bit_1,
    if (cx > sx) then M_append(cx + 1, cycz) else M_append(cx − 1, cycz) end if,
    if (cx < sx) then M_append(cx − 1, cycz) else M_append(cx + 1, cycz) end if
)

Note that the two if-then-else statements, which are the second and third parameter of the macro occurrence, are functionally equivalent in terms of what, if anything, will be appended to the give_to_list (this same functional equivalence is true for the if-then-else statements in the other two occurrences of this macro in the below selection code; the only difference between the if-then-else statements in the three macro occurrences is the axis—either X, Y, or Z—involved). The first parameter is, in effect, a random value whose value is either 0 or 1. If its value is 1, then the first if-then-else statement (parameter 2) is executed; otherwise, the second if-then-else statement (parameter 3) is executed.

Also regarding the two if-then-else statements in the macro: By analogy with physical-computer machine code, the computing-element machine-code for the comparison (cx > sx) will take the exact same execution time that the computing-element machine-code for the comparison (cx < sx) will take. And also by analogy with physical-computer machine code, adding 1 to a variable will take the exact same execution time as subtracting 1 from that variable, which means, in the above macro occurrence, that the execution time to compute (cx + 1) will be the exact same execution time to compute (cx − 1). This means that each of the M_append() occurrences in the above macro, will take the exact same execution time. Thus, the A and B parts of each of these two if-then-else statements have the exact same execution time. This only leaves the time difference etd regarding how much more execution time each of the two if-then-else statements need in total to do the comparison and execute just the A part, compared to doing the comparison and executing just the B part.

In the below selection code, the M_determine_which_of_these_two_ifs_executes() macro is used for all three axes, X, Y, and Z. The end result is that, as the separation distance along an axis between the sender and receiver increases (denote this separation distance as n), the etd time penalty when executing part A instead of part B will be more evenly distributed between the two directions along that axis, so that each direction along that axis will have a total time penalty from executing part A, of about (½ × n × etd). Note that the value of n is the absolute value of ((sender’s coordinate for that axis) − (receiver’s coordinate for that axis)), which is the number of computing elements along that axis that the sent message_instance will have to pass thru to ultimately get to the receiver, and at each of these pass-thru computing elements—with the sole exception of whichever computing element on the path from sender to receiver is adjacent to the sender—this pass_this_message_along() routine will be executed for that sent message_instance. In conclusion, because of the M_determine_which_of_these_two_ifs_executes() macro, directional bias along each of the three axes is removed, and neither direction along an axis has an execution-time advantage. And this is what is wanted for those learned-program statements that determine the relative locations of particles.
*/
/*
The below selection code has the following structure:

if (condition 1)
    indented-code-block 1
else
    indented-code-block 2
end if

If (condition 1) is true, then indented-code-block 1 is done. If (condition 1) is false, then indented-code-block 2 is done.

Regarding what indented-code-block 1 is doing: Note that the sender’s computing element will give the message to all six of its adjacent computing elements, and indented-code-block 1, in terms of what is appended to the initially empty give_to_list, first moves along the X-axis line that runs thru that sender’s computing element (this XYZ coordinate is appended if it is not more than message_instance.send_distance from the sender). Then, indented-code-block 1 appends the XYZ coordinates of these four adjacent computing elements (if they are not more than message_instance.send_distance from the sender): (cxcy + 1, cz), (cxcy − 1, cz), (cxcycz + 1), and (cxcycz − 1). As a result of condition 1 and indented-code-block 1, indented-code-block 2 will always have the same starting point, regardless of the cx value (regardless of whether cx equals sx, or not), in terms of which computing elements in the circle have already gotten the message (or will get the message) from indented-code-block 1.

Regarding what indented-code-block 2 is doing: indented-code-block 2 will append the XYZ coordinate of each computing element—that is not the sender nor any of the six computing elements adjacent to the sender nor any computing element that will, in effect, get the message from indented-code-block 1—that is in the circle that has a width of one computing element, and this circle’s center is at the XYZ coordinate (cxsysz), and this circle is perpendicular to the X axis of the computing elements. Note: At cx equals sx, the radius of the circle is message_instance.send_distance.

Note: There are three different versions of this selection code that are symmetrically the same: the circle of indented-code-block 2 is perpendicular to the X axis of the computing elements, which is the version shown below; the circle of indented-code-block 2 is perpendicular to the Y axis of the computing elements; the circle of indented-code-block 2 is perpendicular to the Z axis of the computing elements. For the two versions not shown, the other parts of the selection code would be changed accordingly. Also, note that for each of these three different selection-code versions, indented-code-block 2 itself has two different versions (in the selection-code version shown below, the ifs in indented-code-block 2 that compare cz with sz, can be changed to ifs that compare cy with sy, and the rest of the code in indented-code-block 2 would be changed accordingly).
*/
/*
To make clear how the below selection code works, here are several examples:

if (cy equals sy) and (cz equals sz) and (cx < sx) then the give_to_list will have these five XYZ coordinates (assuming the distance from the sender to each is not more than message_instance.send_distance): (cx − 1, cycz), (cxcy + 1, cz), (cxcy − 1, cz), (cxcycz + 1), (cxcycz − 1).

if (cz equals sz) and (cy < sy) then the give_to_list will have these three XYZ coordinates (assuming the distance from the sender to each is not more than message_instance.send_distance): (cxcy − 1, cz), (cxcycz + 1), (cxcycz − 1).

if (cy < sy) and (cz > sz) then the give_to_list will have one XYZ coordinate (assuming the distance from the sender to it is not more than message_instance.send_distance): (cxcycz + 1).

*/
if ((cy equals sy) and (cz equals sz))  /* condition 1 */

/*
indented-code-block 1

Note: (cx not equal sx) here, because this_CE is not the sender. Thus, at this point in the code either (cx > sx) or (cx < sx).
*/
M_determine_which_of_these_two_ifs_executes(
    random_bit_1,
    if (cx > sx) then M_append(cx + 1, cycz) else M_append(cx − 1, cycz) end if,
    if (cx < sx) then M_append(cx − 1, cycz) else M_append(cx + 1, cycz) end if
)
M_append(cxcy + 1, cz)
M_append(cxcy − 1, cz)
M_append(cxcycz + 1)
M_append(cxcycz − 1)

else

/* indented-code-block 2 */
if (cz equals sz)
    /* Note: (cy not equal sy) because otherwise condition 1 above is true. */
    M_determine_which_of_these_two_ifs_executes(
        random_bit_2,
        if (cy > sy) then M_append(cxcy + 1, cz) else M_append(cxcy − 1, cz) end if,
        if (cy < sy) then M_append(cxcy − 1, cz) else M_append(cxcy + 1, cz) end if
    )
    M_append(cxcycz + 1)
    M_append(cxcycz − 1)
    go to label:skip_over
end if
/* Note: at this point in the code, (cz not equal sz). */
M_determine_which_of_these_two_ifs_executes(
    random_bit_3,
    if (cz > sz) then M_append(cxcycz + 1) else M_append(cxcycz − 1) end if,
    if (cz < sz) then M_append(cxcycz − 1) else M_append(cxcycz + 1) end if
)
label:skip_over

end if

/*
Note: In July 2017, I wrote a program in Mathematica’s programming language to test the above selection code to make sure that it was correct and flawless and that it filled without duplicates a sphere of radius send_distance. Mathematica is a commercially available program which I bought for my own use in June 2017 to help me with my gravity algorithm (see the mention of Mathematica in footnote 23). The testing was successful and the above selection code is correct and flawless. Note: “filled without duplicates” means that each computing element within the sphere of radius send_distance that is centered on the sender’s computing element, is given the message exactly once (excluding the sender, and the sender’s six adjacent computing elements which got that message from that sender and not from the above selection code). Note: this test program did not implement nor test the random selection between two functionally equivalent if-then-else statements done by the M_determine_which_of_these_two_ifs_executes() macro.
*/

/*
Copy the message_instance to each adjacent computing element whose XYZ coordinate is in the give_to_list.

The below for goes in order, beginning with the first element in give_to_list, if any, and ending with its last element. However, note that the order of the XYZ coordinates in give_to_list is unimportant, and also note that the give_to_list can be empty if the XYZ coordinate(s) that would otherwise be in give_to_list are more than message_instance.send_distance from the sender.
*/
for each adjacent computing element whose XYZ coordinate is in the give_to_list
do
Give that adjacent computing element the message_instance by copying that message_instance to that adjacent computing element.
end do
end for

return  /* exit this routine */
}

Several Properties of this Sphere-Filling Message-Transmission Algorithm

Given a message of size s (s is the size of the message_instance), a send_distance, a sender computing element (the computing element from which this message was sent), and a receiving computing element (the receiver is a computing element that is not more than send_distance from the sender, and is holding a particle that is a recipient of the sent message), the following are several properties of the sphere-filling message-transmission algorithm given above:

The selection code in pass_this_message_along() is optimal in the following way: Regardless of what the XYZ coordinates of the sender and receiver are, the message_instance received by that receiver will have moved along a shortest path thru adjacent computing elements between that sender and receiver. More specifically, the message_instance.transfer_count at the receiver will have the smallest transfer_count possible, going from that sender to that receiver. (Note: the number of shortest paths between the sender and receiver, each having the same message_instance.transfer_count at the receiver, is either 1, 2, or 6, depending on the XYZ coordinates of the sender and receiver: regarding the X, Y, and Z components of an XYZ coordinate, if two of these three components have the same value for both the sender and receiver—for example, the X component of both the sender and receiver is 8, and the Z component of both the sender and receiver is 13—then there is only 1 shortest path between the sender and receiver; if only one of these three components have the same value for both the sender and receiver, then there are 2 shortest paths between the sender and receiver; if none of these three components have the same value for both the sender and receiver, then there are 6 shortest paths between the sender and receiver, depending on which of the three axes is moved along first, and then which of the remaining two axes is moved along next, and then moving along the one remaining axis to the receiver. Note that in the case of there being 6 shortest paths, the version of the selection code given in pass_this_message_along() above, always moves along the X axis first, then along the Y axis, and finally along the Z axis to get to the receiver.)

Consider the following question: How much time is needed for the message to move from the sender to the receiver? Presumably, the time needed to copy a message of size s is proportional to s. Thus, the larger the message, the more time needed to copy that message from a computing element to an adjacent computing element. Also, because more time is needed to copy a larger message, the computing-element program imposes a limit on the maximum size of a message, so that message transfer is always a fast process. Given the “very high priority” at which pass_this_message_along() runs, there will be an average time for transferring a message of size s from a computing element to an adjacent computing element (denote this average transfer time for a message of size s, as time T). The time needed for the message to move from the sender to the receiver is approximated by:

(message_instance.transfer_count at the receiver) × T

Denote the XYZ coordinate of the sender as (x1, y1, z1), and denote the XYZ coordinate of the receiver as (x2, y2, z2), and note that the X, Y, and Z components are integers and the transfer_count is an integer. With regard to the XYZ coordinates of the sender and receiver, what will the transfer_count at the receiver be? The distance d between the sender and receiver is given by the distance formula:

d = square_root_of((x2 − x1)2 + (y2 − y1)2 + (z2 − z1)2)

Let a = (x2 − x1), let b = (y2 − y1), and let c = (z2 − z1). The rewritten distance formula is:

d = square_root_of(a2 + b2 + c2)

Regarding the pass_this_message_along() routine, note the following:

  1. Given the selection code in pass_this_message_along(), the following equation is always true for the receiver:

    message_instance.transfer_count = (abs(a) + abs(b) + abs(c))

    Note that abs() is a math operator that returns the absolute value of the given number. For example abs(0) is 0, abs(8) is 8, and abs(−8) is 8. For any real number r, abs(+r) is r, and abs(−r) is r.

    As an example regarding the sender and receiver, if the sender’s XYZ coordinate is (4, 13, 1), and the receiver’s XYZ coordinate is (3, 8, 5), then the message_instance.transfer_count at the receiver will be (abs(3 − 4) + abs(8 − 13) + abs(5 − 1)), which is (abs(−1) + abs(−5) + abs(4)), which is (1 + 5 + 4), which is 10.

  2. Denote the integer value of the message_instance.transfer_count at the receiver as n. The distance between the sender and receiver is maximized when only one of the three terms abs(a), abs(b), and abs(c), is nonzero.

    In this case, the distance d between the sender and receiver (computed using the distance formula) is simply the absolute value of whichever term, a, b, or c, is nonzero, which gives a distance of n.

    For example, if the message_instance.transfer_count at the receiver is 9, and abs(a) is 9, and abs(b) and abs(c) are both zero, then the distance between the sender and receiver is square_root_of(92) which is 9.

  3. Denote the integer value of the message_instance.transfer_count at the receiver as n. If n is at least 3 and n is a multiple of 3, then the distance between the sender and receiver is minimized when abs(a) = abs(b) = abs(c), in which case the value of each of these three equal terms is (n ÷ 3).

    In this case, the distance d between the sender and receiver (computed using the distance formula) is square_root_of(3 × ((n ÷ 3)2)), which simplifies to (n ÷ square_root_of(3)).

    For example, if the message_instance.transfer_count at the receiver is 9, and abs(a), abs(b), and abs(c) each have the value of 3, then the distance between the sender and receiver is square_root_of(32 + 32 + 32), which is 5.19615 (accurate to 5 decimal places).

Regarding notes 2 and 3 above, and assuming the same message_instance.transfer_count value—the same n value—for each of the two notes, the ratio of the largest distance between the sender and receiver (note 2), divided by the smallest distance between the sender and receiver (note 3), is:

n ÷ square_root_of(3 × ((n ÷ 3)2))

The above ratio for n > 0, simplifies to square_root_of(3), which is 1.73205 (accurate to 5 decimal places). Denote this ratio constant as SQUARE_ROOT_OF_3, which is used in subsection 3.8.6 to compute how much time to allow for all the replies to a sent query message to be received by the bion that sent that query message.

Given a sphere of radius send_distance that is centered on the sender’s computing element from which the message was sent: A receiver at that sphere’s surface that is on the shortest path from that sphere’s center to that sphere’s surface (note 2 above, applies in this case), will receive the sent message after approximately this much elapsed time since the message was sent (time T is defined above as the average time needed to transfer a message of size s from a computing element to an adjacent computing element; presumably, given the size s of the message, the computing-element program can compute a close approximation of this average transfer time T):

send_distance × T

And a receiver at that sphere’s surface that is on the longest path from that sphere’s center (note 3 above, applies in this case), will receive the sent message after approximately this much elapsed time since the message was sent:

SQUARE_ROOT_OF_3 × send_distance × T