# Robust-first Computing Wiki

### Site Tools

dev:questions_ulam

## Week One

### Q: The range of Unary

What is the range for an `Unary` number? How many bits does it take?

A: To understand the range of an Unary number, we first have to know how it is represented. An Unary(n) number takes n bits. It represents an integer of the number of 1's in it. For example `Unary(5) myUnary5 ` takes 5 bits. There could be 0 to 5 1's in it. So the range is from 0 to 5.

That explains why the following code will output 1,3 and 7 when the value I expected is only 0,1,2,3.

```DebugUtils du;
Unary(4) ns;
if(ns==0){
ns=1;
}
else if(ns==1){
ns=2;
}
else if(ns==2){
ns=3;
}
else if(ns==3){
ns=0;
}
du.printContext();```

### Q: More about the bits in Unary

If the value of an myUnary5 is `1`, does it mean the possible bits that myUnary5 holds could be '00001', '00010', '00100', '01000' and '10000'?

A: 30-May-2015 02:56:33PM-0600: Yes, a `Unary` value that contains a single 'on' bit will have value `1`, regardless of its position. So, for example, in a `Unary(3)`, there is only one representation of zero (`000`), and one representation of three (`111`), but there are three possible representations for one (`001`, `010`, `100`) and three representations for two (`110`, `101`, `011`). Only the number of one bits (known as the 'population count' or 'popcount') matters in determining a `Unary` value.

## Week Two

### Q: Dynamic atom coloring?

We can override some properties of an element, such as its color, when we were programming C++ to create elements on the MFM. How can we do the same thing in ULAM? I want to create two types of Res with different colors. (This is a simplification of the Aura and Medicine element. Later I will convert them to real Aura and Medicine)

A: 28-May-2015 01:04:05PM-0600 There was a getColor() special function to allow the ULAM programmer to determine atom colors at runtime, but that mechanism is currently broken by the in-progress Site redesign efforts. Hope for getColor or some replacement to reappear within a week!

### Q: Access other atom data members?

Sometimes we want to get other Atom's data member. In the 'Aura and Medicine' game, a Medicine atom will compare the density that it observed with the density stored in another Aura atom. How can we access the data member of other atoms? I tried to write like this but got compile errors:

```Atom a = ew[slot];
Int yourDensity = a.density;```

A: 29-May-2015 04:37:12AM-0600: Probably the most straightforward is to use an 'is' expression combined with a cast:

```Atom a = ew[index];
if (a is Foo) {
Foo f = (Foo) a;    // Note that f is a copy of a!
Int n = f.fooField;
// ..use n for something..
} // else a is not a Foo```

If you want to modify fields of an atom this way, you need to write the changes back:

```element Foo {
EventWindow ew;
Int(7) fooField;

Void behave() {
if (ew[1] is Foo) {
Foo f = (Foo) ew[1];  // Makes a copy
++f.fooField;         // Modifies the copy
ew[1] = f;            // Updates eventwindow
}
}
}```

### Q: WindowServices next() returning -1?

I have a problem using `WindowServices` with a `for` loop. I printed out the value of `ws.next()`. It is '-1'. I think that's why the code inside the for loop is not performed. Please tell me again how to pick a nearby neighbor in my EventWindow so that I can read or modify its fields.

```
WindowServises ws;
ws.reset(0,4);
Signal s;
Int st=au.getType((Atom) s);
if(ws.scan(st)){
density=ws.getHits(0);
if(density>0){
du.print((Int) ws.next());
for (Int idx = ws.next(); idx >= 0; idx = ws.next()) {
Atom a = ew[idx];
if (a is Signal) {
}
}
}    ```

A: 29-May-2015 06:24:01PM-0600: The `WindowServices next()` method returns -1 when there are no more event window indices to scan in your chosen range.. but the main issue here is: You don't want to use both a `ws.scan()` call and a for loop with `ws.next`, you want one or the other. If you use scan, then you use `getHits` to see if anything matched, and `getPick` to get a randomly-chosen match. That code has got other issues too (e.g., `WindowServices`).

### Q: How to access event window site number when using ''WindowServices scan()''?

Thank you! I fixed the code. This time I use the for loop on ws.next(). I wanted to use `ws.scan(someType)` but then if I used `ws.getPick(0)` to find a match, how would I know its actual index in the event window?

```WindowServices ws;
Random rdm;
ws.reset(1,4);
Request r;
Int rt=au.getType((Atom) r);
for(Int idx=ws.next();idx>=0;idx=ws.next()){
Atom a= ew[idx];
if(a is Request){
Request you=(Request) a;
if(density>you.density){
if(rdm.oneIn(2)){
ew.swap(0,idx);
}
}
}
}```

A: 29-May-2015 11:08:39PM-0600: As long as the corresponding `ws.getHits` returns greater than zero, then return value of `ws.getPick` is the event window index! You can do stuff like:

```WindowServices ws;
ws.reset(1,4);
Request r;
Int rt=au.getType((Atom) r);
if (ws.scan(rt)) {            // Any matches for rt?
Atom a = ew[ws.getPick(0)]; // Yes! Access chosen slot
if(a is Request){           // This 'if' will always succeed..
r = (Request) a;
.. use r.density etc ..
}
}```

or even this:

```WindowServices ws;
ws.reset(1,4);
Request r;
Int rt=au.getType((Atom) r);  // Get type of element Request
if (ws.scan(rt)) {            // Any matches for that?
r = (Request) ew[ws.getPick(0)]; // Yes! Access slot of chosen one
.. use r.density etc ..
}```

because that particular `ws.scan(rt)` can only return true if `ws.getPick(0)` is going to return the event window index of a `Request` atom. (It's not this easy, though, if you are scanning for multiple things simultaneously.)

### Q: Does ws.getPick(typeIndex) only return one site? How to access each site within an event window?

Thank you! Now I understand that `ws.getPick(typeIndex)` returns an event window index. `ws.getPick(typeIndex)` can randomly pick one atom of this type. When I want to select an atom of this type but also has the maximum value of a certain data member, I should use the for loop to check each atom of this type and get this maximum atom. Like here I want to find the `Request ATOM` which has the max density value within this EventWindow.

A: 31-May-2015 12:51:43AM-0600: To select an atom based on anything other than its type, in general you'll need to write a loop explicitly, rather than using `scan()` – although `WindowServices` can help with the event window indexing.

But even when you do need to loop, we have `SelectorServices` to provide some help for simpler tasks like finding and picking fairly among maxima and minima. Here are two `SelectorServices` examples. The first, `SSDemo1`, uses `SelectorServices` in a relatively general way, while the second, `SSDemo2`, is a bit optimized for shorter code.

SSDemo1.ulam
```/**
SSDemo1s share the highest Score among their connected group.
*/

element SSDemo1 {
// Typedefs
typedef Unsigned(8) Score;

// Utilities
EventWindow ew;
Random random;
DebugUtils du;

// Data members
Score val;

Void behave() {
if (val == 0) // randomize initial vals
val = random.bits(val.sizeof);

WindowServices ws;    // Scanning support
SelectorServices ss;  // Selection support

ws.reset(1,4); // Scan all but us (for this example)
ss.reset();

for (Int idx = ws.next(); idx >= 0; idx = ws.next()) {
Atom a = ew[idx];
if (a as SSDemo1)
ss.maximize(idx, (Int) a.val);
}
// This code is fairly general, but cumbersome.  Compare SSDemo2
Int sidx = ss.getSelectedKey(); // The site that maximized
SSDemo1 f = (SSDemo1) ew[sidx]; // which we know is a SSDemo1
if (f.val > 0)                  // ..if they've been initted
val = f.val;                  // ..pick up their val
du.printContext();              // and report for debugging.
}
}
}
```
SSDemo2.ulam
```/**
SSDemo2s share the highest Score among their connected group.
*/

element SSDemo2 {
// Typedefs
typedef Unsigned(8) Score;

// Utilities
EventWindow ew;
Random random;
DebugUtils du;

// Data members
Score val;

Void behave() {
if (val == 0) // randomize initial vals
val = random.bits(val.sizeof);

WindowServices ws;    // Scanning support
SelectorServices ss;  // Selection support

ws.reset(0,4); // Scan everyone including us
ss.reset();

for (Int idx = ws.next(); idx >= 0; idx = ws.next()) {
Atom a = ew[idx];
if (a as SSDemo2)
ss.maximize((Int) a.val);  // Don't need the idx this way..
}
// We scanned ourselves, so we know ss.selectionMade() will be
// true.  So we just take the chosen value (even if it was ours).
val = (Score) ss.getSelectedValue();
du.printContext();
}
}
```

### Q: How to change the size of the MFM simulator?

Sometimes the canvas is too big for my experiment. If I don't want those atoms diffuse too far away, I will draw a box of `Wall`. Can we change the size of MFM simulator?

A: In version 3, the `mfms` simulator has a nice new feature: You can specify the grid size (and even the tile size!) on the command line.

Read the very beginning of the output from 'mfms -h' about geometry. If the geometry is specified is has to be the first argument on the command line.

Try something like:

`you@linux\$ ..path../mfms {2C2} -flags -what -ever`

or even

`you@linux\$ ..path../mfms {1H1} -flags -what -ever`

### Q: Do smaller grid geometries make the simulator run faster?

Thank you! That's better than drawing `Walls` by hand. The right side is the resized MFM simulator by {2C2}. And isn't the smaller simulator running faster?

A: 31-May-2015 01:06:01AM-0600: It depends somewhat on your hardware – in particular, how many real cores you have, but yes, in general a smaller grid geometry – fewer and smaller tiles, down to some limit – will typically be faster than more and larger tiles. Any single tile geometry will be running single-threaded, though, so in some cases multiple smaller tiles will be faster than one bigger one – you'll need to experiment some, if maximizing AER is crucial. Also, if you type `a` a few times after typing `i` in the simulator, it will display the AER it is producing, so you can get a rough sense of what's faster and slower.

On a separate point, note that the “edge of the grid” is somewhat different that a ring of `Wall`s. For example, non-existent sites return `false` from the `EventWindow isLive` method, but sites containing `Wall`s return true. For consistency you might want to draw a ring of `Wall` around the boundary of even a smaller grid.