These are bots that use Boolean style logic gates, created from basic math rules and equations.
Typically this is done to reduce costs associated with normal conditions. These are most likely found in Single Gene bots, but can also be used in more normal bots.
True or False
True conditions result in the memory location being multiplied by 1. A false results in a 0 or -1 multiplication, stopping the action.
The simplest memory locations to use are those that are already either a one or zero; .hit, .edge, and .fixed are prime examples.
20 .up *.hit mult store .hit *.hit mult dec
This code moves the bot whenever it is hit, then zero's the memory location of hit. Since hit can only have the values zero or one it's a breeze to use.
Suppose now we want the bots to react when a value is zero, like say looking around when nothing is seen. A typical mult will cause the bot to cancel the action. To use zero we'll have to convert it into a one.
314 rnd .aimdx *.eye5 sgn 1 sub -1 mult mult store
The middle is the code we're interested in. First the sign(sgn) of eye5 is found, then one is subtracted(sub) from it; resulting in zero(positive value) or -1(no value). Next it is multiplied by -1, perhaps the most important step this takes advantage of zero remaining the same and -1 becoming a positive one. At last we have our true value which we multiply by aimdx to make the bot turn only when it doesn't see anything.
The "-" operator can be used now instead of "-1 mult" to negate a value.
Possibly the Compliment operator "~" could be used for direct bit flipping, ie. zero to one or one to zero.
Equal or Not?
The next step is to allow the bots to determine whether or not a sysvar is equal or not equal, to a particular value or another sysvar.
This is easily accomplished by reducing the sysvar to a more usable value in this case zero or one.
314 rnd .aimdx *.refeye *.myeye sub sgn abs 1 sub -1 mult mult store
Similar to the previous DNA this will cause a bot to turn, however this DNA will only activate if the bots are related(hopefully).
First refeye is subtracted(sub) from myeye, resulting in a zero or a variable X. Since X could be positive or negative we find the sign and absolute of it, resulting in our favorite 1. With help from our conversion DNA, they flip and we have our true statement of one that we multiply by allowing the bot to avoid kin.
Greater or Less?
Most widely used of all conditions is greater than and less than. Mostly in regulatory functions these allow bots to determine relationships between values in a less cut and dry manner than equal or not.
50 300 *.nrg 5000 sub sgn 0 floor mult store
This DNA allows a bot to reproduce whenever it's energy level is greater than 5000. When this occurs the sign returns one and the bot reproduces. As a negative memory location is seen by the program the same as a normal memory location we use (0 floor) to make sure the result is either a 1 or 0.
Caution: When using sgn care should be taken with the negative results, compound use of solitary sgns can result in false results.
If we wanted a less than we would flip 5000 and nrg or if necessary use the conversion DNA to obtain the values we want.
For most operations using mult works well to form an AND.
X mult Y mult Z mult
In this pseudo code X, Y, and Z represents expressions evaluating to a one or zero. If all are 1 or true the action occurs. If even one of the expressions is zero or false the action is canceled.
Suppose we want to shorten the DNA by using OR allowing an action even if one of the expressions is false? To do this we can add the numbers then find their sign and absolute value to obtain our one.
X Y add Z add sgn abs mult
If one or more is 1 the action occurs. If all are zero it is canceled. A practical use of this is shown below.
314 rnd .aimdx *.refeye *.myeye sub sgn abs 1 sub -1 mult *.eye5 sgn mult *.eye5 sgn 1 sub -1 mult add sgn abs mult store
Combining two of the DNAs we've seen before this will cause the bot to turn whenever nothing or kin are seen. Useful in terms of shortening DNA length and allowing similar actions to be activated by different conditions.
To continue we need to understand some important properties of zero, one, and negative one; as they relate to one another in DB.
Simple yet complex in application. The last two are worth a mention, in DB division by zero causes no error, but generates a typical zero. Useful in coding as the alternative form of sgn abs, dup div widely used prior to the upgrade.
For X, Y, Z equal to either (1,0,-1)
X Y mult Z mult ' = A
A equals 1 if no value is zero and if an even number or none of evaluations are negative.
It is possible to create 'extra memory' or 'long term memory' for your bot using two or operators and the ~
For X1, Y1, X2, Y2, allowing for only a 1 or 0 value
set X1 and Y1 to a value of 0 or 1 as two inputs. X2 and Y1 have to be dependent on the return value of the operator.
X1 X2 add ~ Y2 store Y1 Y2 add ~ X2 store
This will create a R/S latch with high-level activation. A low level activation would require AND gates instead of or gates. The ~ needs to be there for the NOT function, or NOR/NAND in this case. As you can see, when Y1 goes high, the output of the NOR gate on the bottom must be 0 (because when either NOR input is high, the output is 0). This sets Y2 to 0. This same 0 goes to the lower input on the NOR gate at the top; Since X2 must be low (since Y2 is high), both inputs to the NOR gate at the top are 0. Therefore, since both inputs are 0, it outputs a 1. This 1 hits the top input of the bottom gate, keeping the gate on (and setting Q to 1), and the latch remains stable in this state until Reset goes high. Similarly, the opposite happens when Reset goes high. The workings of this latch may seem confusing at first, but if you follow the logic paths you should be able to understand it clearly. This makes for an excellent operator for a search algorithm, or even a 'drive/go' gene. Basically makes two comparisons at once.
Something like: Y2 X2 add 20 mult .vel store This could be used to set the speed to 20 when in memory or active mode. However this would require another gene to slow him to a stop faster than friction would.
Further development of their 'memory' would require more inputs: Enable, and Write
Enable requires an and function of two values, and gives an output to either X1 or Y1, depending on how you are creating the R/S latch.
Example: Enable (another value such as .hit or .floor) and X1 (or Y1) mult .(anyvalue or it could be) X1 or Y1 if you are using it create a memory gene. E *.hit and X1 mult Y1 store
The write value would be denoted by the user as some sort of sensor preferably. Such as eye5.vsnd would take either X1 or Y1's place, but should be a different variable from the Enabler, unless the gene calls for instant activation when the Enable says 1.
If you want Enable to be compared with Write, an AND function between the two variables assigned to them would create a comparison between 3 or 4 things. More development would be to create several genes like this and link them together between outputs and inputs. This would require a decoder if you only using two checkpoints or inputs.
The gene would look something like this:
- .eye5 *.floor mult Z store
Z ~ Z^ store
- .hit *.floor mult E store
E ~ E^ store
For an eight bit array of 'ram' genes all of these points of data stored become Enable values for the array. A Write Enabler, such as .refeye or refpoison would have to be denoted the variable which actived the write gene or X1 (Y1 for NAND R/S Latches). Comparisons between the Write Enabler and Enable would create a greater comparison complex. Please note that the Decoder, and Enabler used are for NOR R/S Latches, which only remember bits when the Y1 value is 'High' or 1.