Q: I am working on an image processing experiment. If I use "single-module" everything works well, but if I don't some horizontal lines are shown on the screen. There are 8 lines, like the number of modules in our CAM-8. What should I do? A: Your problem is that somewhere in your experiment you have a "run" instruction which isn't preceded by exactly one "kick" instruction. This will work fine with one module, but will cause an error in the way that multiple modules are glued together, so that you see artifacts at the boundaries between modules. If you have a run with no kick, you need to put a "kick" before it (with no amount specified, so that it will be a kick of zero). If you have multiple kicks before a run, you need to combine them into a single kick. Q: I change my experiment and load it, but the behavior of CAM-8 doesn't seem to change. Why not? A: If you use "?rule>table" in your experiment, as most of the demos do, then the software saves a copy of your rule-table to disk the first time you compile it, and uses the version on disk for subsequent loads, to speed up loading the experiment ("rule>table" is similar, but it doesn't try to optimize by saving or using anything on disk). With "?rule>table", even if you change the rule, the version on disk is used unless you give "l" (load) an argument of 0 (press the number "0" before pressing the letter "l"). You can also force a table to be recompiled by deleting the version on disk -- its name is of the form ..tab . Q: I'm using the "3x3.hood" neighborhood, and CAM-8 doesn't seem to be obeying the rule I've specified. I've tested the rule on simple cases by assigning values to neighbors (eg. "0 -> cell 1 -> center 1 -> north update"), then executing the rule definition and looking at the results (eg. "update center .") and it looks fine. But when I fill the space with the case that I've tested and run CAM-8 on it, it does the wrong thing. What's up? A: You may simply need to recompile the table (see previous question). You also may be forgetting to include the word "propagate" at the end of your rule. 3x3.hood expects your rule to put copies of the center cell into "north", "south", etc., so that it can kick these copies in the various directions and make them available as the various neighbors. The word "propagate" makes these copies. If you don't include this word in your rule, then cells cannot see their neighbors. Finally, if you load an initial state for your space and don't run a "propagate-step" on it (which runs a rule consisting only of "propagate"), then the first updating step will not do the right thing. Q: Cellular Automata theory provides two ways to solve the problem about how to use rules at the edges of the space defined. In my experiments I have to process images, so that it makes no sense to use gluing: at the top of an image I have sky, at the bottom roads, and I don't want to mix such different information inside my rules. Is it possible, on CAM, to use the other approach for CA, that is to isolate the North edge from the South one (and East from West) by defining special fixed "external" cells surrounding the space? A: On CAM, the space is glued (periodic) in hardware: any other boundary conditions must be simulated in software. The way to do this is to use extra bits to mark the boundaries, and follow a different rule there. For example, you could use one extra bit to mark all edges of the space, and make your rule be such that these boundaries remain fixed. This achieves essentially what you asked for, since all interior cells will then see fixed values at the edges. The other simple boundary condition is reflective boundaries: cells at the top see the same neighbor above them that appears below, cells at the right see the same value to their right that appears to their left, etc. There are nine cases (four edges, four corners, and the interior), and so you would need to use four bits to tag each cell with an indication of which case it belongs to. One bit might be called "boundary?", and the three others might be called "boundary-type". Your rule could explicitly use this information, or you could hide it in the definitions of the neighbor names. If you want to add reflective boundary conditions to an existing neighborhood, such as "3x3.hood", you should copy the ".hood" file to a new name and remove some of the existing neighbors, and redefine them for use as boundary markers. You should also eliminate any kicks that refer to the neighbors that have been removed (see "3x3x1.hood"). Q: If I need to use, say, information contained in cell (x,y)=(48,97) of my defined cellular space and put it in a constant previously defined, how can I do this on CAM-8? A: You can read and write cells on CAM using the "line-io" routines. These actually read and write entire rows from CAM, to be more efficient. Thus if you use these in a loop, its fastest to access this data in row-major order. The relevant words are: begin-line-io \ use before a sequence of i/o ops end-line-io \ use after a sequence of i/o ops read-point (s x y -- value.field ) \ uses current field write-point (s value.field x y -- ) \ uses current field The "begin" and "end" words may actually result in running shift steps on CAM, and so its best to put them outside of your inner loop. Suppose you wanted to read the value in a field called "heat" at locations (48,97) and (48,98) and store these in constants "pixel-a" and "pixel-b". Your program might look something like this: begin-line-io 48 97 heat field read-point is pixel-a 48 98 heat field read-point is pixel-b end-line-io Note that these words are used in a program that runs steps on CAM: it would make no sense to include such commands within the definition of a lookup table! Q: I have a problem understanding how the "kick" operator works. Let us consider an example. varible dx 7 dx ! define-step kick-step site-src site kick tmp field dx @ x run end-step : random-kick random 5 mod dx ! kick-step ; this is update-step It seems that the value of dx used in "kick-step" is not the current one but rather given in the initial assignment. How can I change the vector of movement on each update step? A: The purpose of "define-step" is to produce a compiled list of CAM machine-language instructions, which will be scheduled whenever you execute the name of the list (in your example, "Kick"). The contents of the list is fixed at compile time, and contains no variables -- only the values that variables had at compile time are relevant. If you want to have variable data at execution time, but still use precompiled step lists (for maximum execution speed), then the best thing to do is compile several versions of the same step list, and select one of them at execution time. For example: define-step kick0-step site-src site kick tmp field 13 x run end-step define-step kick1-step site-src site kick tmp field 29 x run end-step : Main random 2 mod {{ kick0-step kick1-step }} ; this is update-step Note that the construct with the curly braces is a kind of case statement: the number left on the stack determines which of the words in the braces is executed. Q: I have color images in non-CAM format that I'd like to run through an image processing experiment. How can I do this? A: Look at the man page for the "ppmtopat" program -- this is a unix utility that takes a ppm file, and changes it into a ".pat" file and a ".map" file. If you have a "gif" for example, you type the following at the unix prompt: giftoppm .gif | ppmtopat newname This would produce "newname.pat" and "newname.map", which you use in your experiment exactly as you expect "" .map file>palette "" .pat file>cam show You may want to gzip the .pat file to save space -- "file>cam" will automatically ungzip a pat file as it loads it. Note that there are conversion programs in the same directory as "giftoppm" to convert between a very wide variety of image formats: your original color images can be in almost any format. Q: Is it alright to leave CAM-8 turned on all of the time? A: There's no reason that CAM-8 shouldn't be on all the time -- most of our machines here are on all the time. The main reason we turn them off sometimes is that they are a bit noisy. Q: Can we use the CAM remotely? A: As long as no one else is using CAM, you can run CAM from an xterm window running anywhere in the world. If you have the DISPLAY environment variable set correctly on the machine attached to CAM, and the "xhost" permission set correctly on the remote machine, then you just run "step" on the machine attached to the CAM. You can then start an X-window display for CAM by pressing the "x" key. If you try to start "step" and someone else is already running it, the the program will print out a message telling you that the CAM-8 hardware isn't available, and will exit. If you type "step-status", it will tell you who is running CAM, if they've been idle for a long time, and if they've left a message using the "reserve-cam" command. For example, if I'm running CAM on "im3", and I'd like to leave a simulation running until 5pm, I would go to a free xterm window and type, reserve-cam "Until 5pm" Then when someone types "step-status", they'll get a message something like this: nhm is running step on im3 (process 1524 on ttypa). User: nhm Date: Fri Nov 28 1:57:15 EST 1997 Reserved: Until 5pm If "step" has been idle for a long time, or if it is past the time that the machine was reserved for, you can kill the current "step" process by typing "steal-cam". This process execute in super-user mode, and so can kill someone else's process. This command is also useful if some software error has managed to hang the "step" process, and you'd like to kill it. Note that in general if "step" hangs, you may want to first check that the CAMBus cable hasn't come loose, and that CAM is still on, before you kill the "step" process. Q: I'm trying to run CAM-8 remotely through a low-speed connection, and the X-window takes forever to update. What can I do? A: If your connection isn't too slow, you might be able to simply turn the number of steps per display way up, in order to reduce the overhead per display. If you type "8000" in order to run steps in the single-key interpreter, then only every eight-thousandth step will be displayed (about 1 frame every 10 seconds for a 512x512 experiment that runs at full rate). If you're running through a modem, then this solution won't work. A 512x512 image is 256 KBytes of image data, plus a lot of overhead in the X communications protocol. If your modem is 56 kilobaud (7 Kilobytes/sec), it would probably take about a minute to update the X image in ideal circumstances, and probably several minutes under realistic conditions. You need to either find a higher speed connection, or work with much smaller images, or both. A 64x64 image is only 4K bytes, and so you may be able to display it remotely in a second or less. You can either set the size of the space to be small, or just set the maximum display size to be 64 by 64, so that images will be shown assuming that display size. To do this, after starting the "step" program, execute the following code 64 is video-width 64 is video-height You can put this into a file and load it once when you start, or just use the "q" command to drop into the Forth interpreter, type this line, and then type "go" to resume the single-key interpreter. From this point on, all of the experiments that you load or run will only use a 64x64 display, however large the space is. You can zoom in or out, as usual, and the full space will be displayed (as a small image) when the experiment is initially loaded. Q: Is it possible to transfer old CAM-6 rules to CAM-8, at least the ones without user neighbourhoods? A: CAM-8 can run any cellular automaton, in any number of dimensions. You don't need any user connectors or other such accessories -- everthing can be done in software. A few CAM-6-like neighborhoods are defined in software, and some of the more interesting CAM-6 demos have been transcribed for CAM-8. Look, for example, at the "life" demo experiment; you'll undoubtedly recognize many others. Probably the "3x3.hood" (which includes all the Moore and Von Neumann neighbors plus a couple of random bits) will be useful, as well as the "2x2.hood", which implements a 2x2 block-partitioning neighborhood with 4 bits in each cell. It's easy to implement other neighborhoods.