Home 2023 › Forums › Model 2 Discussions › M+ (Ne) Computation
Hello,
This thread will be about M+'s (Ne's) processing, a draft of which can be found here. This is all rather technical, so I'm gonna be walking through the meanings and implications of each line. But, I'll be skipping over the basic P+ (Pe) code. For info on that bit, you can reference this earlier thread. I'll also be referencing ideas in this thread, related to Discrete vs Continuous processing. Okay, here goes!
# Begin associative operation
FOR i to st-memory theObjects length do
FOR e to st-memory theObjects length do
After the initial P+ code, we come across the beginning of the associative (C, or N) code. The first thing we see is two nested FOR loops, one for "i" and one for "e." This will come in handy in the next line. What's important to note here is that we are looking in "st-memory" (short-term memory) at the entire length of its objects.
Short-term memory, or "working memory", refers to all that which exists currently "on the table" of your mind, per se. It is that which is immediately being held in consciousness "right now." This is not long-term memory, but is the sum of all thoughts swimming around one's mind in real-time.
So, the FOR operations are going to check all objects currently existing in our real-time short-term memory for something:
# Check to see if the object's children intersect with another object's children
IF st-memory theObjects[ i ].child-objects intersect st-memory theObjects[e].child-objects do
Here we get to the operation, which says that if an object (i) in short-term memory has sub-elements within it that intersect the sub-elements of another object (e), "do" something. Now, before we get to the "do" part, let me frame what this entails. We can think of this using the following diagram:

^ What we see here are various objects (the circles) in short-term memory. The small numbers within each circle are their child-objects. The red areas are those areas in which child-objects intersect among any two circles (which would be "i" and "e"). So the operation above is looking to see whether any two random objects have intersecting child-objects, and if they do.... "do" the following:
# Make a new object out of the intersecting child-objects
APPEND intersection to intersectingObject
END FOR
END FOR
What we see now is that there is a new variable created called "intersectingObject", which has every instance of an intersection "APPEND"ed to it. In other words, this intersecting object stores all overlaps between any two objects currently in short-term memory -- and makes a new object out of them:

Now, what's unique about this new object is that it is only composed of overlaps. But by making an object out of just the overlaps, each one of these overlaps is taken out of its native context. The new object created is therefore not an object that has any analog in the environment, and is instead a kind of new creation that used existing material to form itself - as a chimera of sorts.

# Make the intersecting object one among short-term memory
APPEND intersectingObject to st-memory
Lastly, this intersectingObject is itself added to short-term memory, where it joins the rest of the objects. Although this seems pretty irrelevant on its own, it's actually a very significant part of the code, because of how this code is cyclical. Because of how this newly made object is added to short-term memory, the next time the code runs, one of the objects that it will run on -- is the very result of the previous cycle. So the results from this chimera become source material from which to make new chimeras, each time potentially becoming more removed from the original context.
Some of the end effects of this code running over indefinite cycles are described in the following:
///////////
The continual application of APPEND intersection to intersectingObject within a FOR loop, on every short-term memory object, creates a new object composed entirely of the intersecting points among them. As a result, this new object is, by itself, decontextualized. It retains no coherent imprint of its origins, and is instead a composited object, or collage, of a set of decontextualized intersections. As such, the object is necessarily simple, lacking informational volume which is not directly purposeful in an associative sense. This causes the generated object to be a caricature. The life-long application of M+ will create a psychology predisposed to caricaturize real-time moments, as they immediately composite together key overlaps and do not include the non-overlapping areas in the new objects.
Due to how APPEND intersection to intersectingObject decontextualizes the new object, the continual omission of source data causes a certain systemic negligence to arise in the M+ function. This systemic negligence creates a disconnect from perceptual information that is not within the intersection. Although M+ is not opposed to any information, non-intersecting information is depreciated, leading to an overall neglect of the spatial context from which objects originate. Over the course of time, this neglect to spatial or original context can lead to a psychology which struggles to mature other areas of cognition related to spatial mapping, unless compensated for by M- or other cognitive activities.
The addition of the intersectingObject into st-memory at the end of each operation via APPEND intersectingObject to st-memory creates a recursive, cyclical effect that leads to greater and greater divergence. Every time an intersectingObject is formed, its decontextualized child-objects become new potential intersections from which the next intersectingObject can be built. As a result, every new object can become further decontextualized from the source data with every cycle of M+. This leads to an indefinite potential divergence to arise, which is limited only by the contextualizations provided by M- and the constraints of the J systems.
------------------
A visual representation of M+ Indefinite Potential Divergence can be seen below:

^ What we see here is the flower-shaped objects (intersectingObjects) produced from prior cycles, all coming together and creating intersections between themselves. Thus, these new intersections are intersections among the intersection-sets. This can happen to no end, which is the reason this is called "indefinite potential divergence." Each rendition has the ability to remove itself even further from any original context, and the results of this compounding has no limit to its potential divergence from any root/discrete starting point. This is also why M+'s behavioral nickname is Potentiality in Model 2.
Is there a formally defined syntax for the CTA pseudocode? I think its readability could be enhanced by replacing the current concoction of camelCase and kebab-case with snake_case. Concerning kebab-case specifically, most compilers I've worked with interpret 'x-y' as a mathematical operation containing two distinct variables and not as a single variable name.
@lautrec - heya! there isn't yet, no. I'm definitely an amateur when it comes to coding, and I mostly rely on javascript & css. If you could recommend a standard syntax, or any edits to the pseudocode notation - I would most certainly appreciate it! 🙂
What do you see as the most useful format to use for this?
(I'm planning to run all this by real programmers after I get the jist of the concept down for all the functions.)
If we are to develop a formal pseudocode standard for the CTA then I think we must first determine the desired level of abstraction. As @safsom pointed out on Discord earlier today, some lines in the current pseudocode point to incredibly complex algorithms. This appears to provide an accurate high level representation of the functions but it also creates a great deal of ambiguity concerning the lower level implementation of many processes. Consider the line:
IF st-memory theObjects[i].child-objects intersect st-memory theObjects[e].child-objects do
It effectively communicates the idea of checking for the intersection of two objects but not the way that such a check would actually work.
A better example of this would be the lines:
# Next, look for more objects adjacent to that one
SCAN visualSystem for adjacent
and:
# Then look for objects far away from that one
SCAN visualSystem for distant
In this case it is unclear exactly what the 'visualSystem' is and how it determines if an object is 'adjacent' or 'distant' to the current object. As a side note, without the comments it is unclear whether or not the current object is even being used as a reference. I think that this specific piece information needs be communicated through the pseudocode and not through additional comments. Going back to the issue of abstraction, I think that both the visual system and the intersection check could be fleshed out with matrical models. The visual system could be seen as a group of vectors forming a feasibility region which parses a 3D space for objects. An object within this space would then contain a 3D vector denoting its position as well as a pointer to an additional n-dimensional vector denoting its properties. For example, the property vector could exist within 4-dimensional space where the four dimensions are 'green', 'round', 'red' and 'smooth.' Thus the properties of a smooth green ball would be denoted by the vector [1, 1, 0, 1] (its location within 3D space would be denoted by the vector [x, y, z]). This model would allow for 'adjacent' and 'distant' to be shown as the result of explicit vector addition or subtraction within a 3D space and for the intersection check to be shown as the process of comparing the property vector elements of two objects. I think there are benefits to fleshing out the pseudocode in this way, however as it becomes less abstract it also becomes more difficult for a layman to understand and relate it to their own thought process. In my opinion this is the theory's greatest strength at the moment and I don't think it would be a good idea to forsake it. That brings me back to the initial problem: determining the desired level of abstraction. In order to retain the benefits of both the high level and somewhat lower level pseudocode, I think it would be best to split the standard into two branches, each with a level of abstraction which accommodates their respective strengths. I intend to write some code in order to simulate the interaction between J- and J+ during the process of articulation, when I'm finished that I think I will have a better idea of the way these two branches could be formatted.
Now to restate my previous comment, I think that the pseudocode should get rid of the current mix of camelCase and kebab-case in favor of snake_case. I personally find snake_case easier to read (not to mention more aesthetic) than camelCase. As for kebab-case, it just isn't allowed by most compilers that I've worked with. In most cases the statement 'x-y' is interpreted as a difference between two distinct variables and not a single variable name. While pseudocode is not directly subject to compiler limitations, I think it would be a good idea to align the two in order to provide a smoother transition. If that is to be done, kebab-case cannot be used.
Considering everything I've said so far, here is how I would rewrite the M+ pseudocode (without any lower level implementations):
FUNCTION mplus
# Load the necessary systems
IMPORT P_System # What is this?
SIDELOAD Visual_System # Is there something significant about SIDELOAD?
# Get the objects from the visual system after pre-processing
short_term_memory.objects = GET Visual_System.preprocessed
# Loop through environment objects which have been perceived by the visual system
FOR i to lenght of short_term_memory.objects DO:
# Check if this object is a duplicate of another object in short term memory.
# This could be some sort of query to J- in order to determine if two objects are
# similar enough to be considered duplicates.
IF number of short_term_memory.objects[i] in short_term_memory.objects > 1 DO:
# There is no need to add the object to short term memory here,
# if the object is being processed in this way then I imagine it
# is already being held in short term memory.
# Look for objects adjacent to the current object.
SCAN Visual_System for objects adjacent to short_term_memory.objects[i]
ELSE DO:
# Ignoring the object seemed redundant since the IF statement was already doing that,
# so I removed it.
# Look for objects distant to the current object.
SCAN Visual_System for objects distant to short_term_memory.objects[i]
# I removed 'END IF' and 'END FOR' because the indentation alone should be enough
# to communicate when these blocks begin and end.
# Begin associative operation.
FOR i to length of short_term_memory.objects DO:
FOR e to length of short_term_memory.objects DO:
# Make sure an object isn't checked against itself.
IF short_term_memory.objects[i] == short_term_memory.objects[e] DO:
skip/continue
# Check to see if the object's children intersect with another object's children.
IF short_term_memory.objects[i] intersects short_term_memory.objects[e] DO:
# Add the intersection to short term memory and remove parent-objects
APPEND intersect to short_term_memory.objects
REMOVE short_term_memory.objects[i]
REMOVE short_term_memory.objects[e]
.
.
.
