Sunday, 20 December 2015

how well do you know X

What does it mean when you ask "how well do you know X?" One possible definition: the amount of "everything" you know about a given ket.

Here, let's drop to BKO to try and demonstrate:
-- load some sample data:
sa: load early-us-presidents.sw

-- define the everything operator:
sa: everything-op |*> #=> apply(supported-ops |_self>,|_self>)

-- apply it to all known kets in the sw file:
sa: map[everything-op,everything] rel-kets[*] |>

-- define operators to measure how big "everything" is:
sa: how-many-everything |*> #=> how-many everything |_self>
sa: how-many-everything-2 |*> #=> how-many everything^2 |_self>
sa: how-many-everything-3 |*> #=> how-many everything^3 |_self>

-- show a pretty table:
sa: table[ket,how-many-everything,how-many-everything-2,how-many-everything-3] rel-kets[*] |>
+-----------------------+---------------------+-----------------------+-----------------------+
| ket                   | how-many-everything | how-many-everything-2 | how-many-everything-3 |
+-----------------------+---------------------+-----------------------+-----------------------+
| _list                 | 6                   | 56                    | 8                     |
| Washington            | 12                  | 1                     | 0                     |
| George Washington     | 1                   | 0                     | 0                     |
| Adams                 | 8                   | 1                     | 0                     |
| John Adams            | 1                   | 0                     | 0                     |
| Jefferson             | 12                  | 3                     | 0                     |
| Thomas Jefferson      | 1                   | 0                     | 0                     |
| Madison               | 12                  | 3                     | 0                     |
| James Madison         | 1                   | 0                     | 0                     |
| Monroe                | 12                  | 3                     | 0                     |
| James Monroe          | 1                   | 0                     | 0                     |
| Q Adams               | 8                   | 3                     | 0                     |
| John Quincy Adams     | 1                   | 0                     | 0                     |
| Democratic-Republican | 2                   | 0                     | 0                     |
| *                     | 0                   | 0                     | 0                     |
+-----------------------+---------------------+-----------------------+-----------------------+
Now, another example:
-- load another set of data:
sa: load bots.sw

-- process this data:
sa: everything-op |*> #=> apply(supported-ops |_self>,|_self>)
sa: map[everything-op,everything] rel-kets[*] |>
sa: how-many-everything |*> #=> how-many everything |_self>
sa: how-many-everything-2 |*> #=> how-many everything^2 |_self>
sa: how-many-everything-3 |*> #=> how-many everything^3 |_self>

-- show a pretty table:
sa: table[ket,how-many-everything,how-many-everything-2,how-many-everything-3] rel-kets[*] |>
+---------+---------------------+-----------------------+-----------------------+
| ket     | how-many-everything | how-many-everything-2 | how-many-everything-3 |
+---------+---------------------+-----------------------+-----------------------+
| Bella   | 19                  | 0                     | 0                     |
| Emma    | 19                  | 0                     | 0                     |
| Madison | 22                  | 38                    | 0                     |
| *       | 0                   | 0                     | 0                     |
+---------+---------------------+-----------------------+-----------------------+
So not a bad start at defining "how well you do know X?".

Now, lets try to automate this a bit, by making use of the fact that loading sw files can do computation.

So first, let's create this sw file (NB: we must not define a context since we want it to be applied to the current context, instead of its own):
$ cat sw-examples/how-well-do-you-know.sw
-- process the data:
  everything-op |*> #=> apply(supported-ops |_self>,|_self>)
  |null> => map[everything-op,everything] rel-kets[*] |>

  how-many-everything |*> #=> how-many everything |_self>
  how-many-everything-2 |*> #=> how-many everything^2 |_self>
  how-many-everything-3 |*> #=> how-many everything^3 |_self>

-- show a pretty table:
  |null> => table[ket,how-many-everything,how-many-everything-2,how-many-everything-3] rel-kets[*] |>
NB: the "|null> => ..." is needed because only valid learn rules are processed during sw file loading. So we just use |null> as a dummy variable. If you leave them out, then our map and table lines would not be processed.

Now, put it to use:
$ ./the_semantic_db_console.py
Welcome!

sa: load fred-sam-friends.sw
sa: load how-well-do-you-know.sw
+------+---------------------+-----------------------+-----------------------+
| ket  | how-many-everything | how-many-everything-2 | how-many-everything-3 |
+------+---------------------+-----------------------+-----------------------+
| Fred | 8                   | 0                     | 0                     |
| Sam  | 7                   | 0                     | 0                     |
| *    | 0                   | 0                     | 0                     |
| null | 0                   | 0                     | 0                     |
+------+---------------------+-----------------------+-----------------------+
And another example:
sa: load breakfast-menu.sw
sa: load how-well-do-you-know.sw
+-----------------------------+---------------------+-----------------------+-----------------------+
| ket                         | how-many-everything | how-many-everything-2 | how-many-everything-3 |
+-----------------------------+---------------------+-----------------------+-----------------------+
| breakfast                   | 5                   | 19                    | 0                     |
| Belgian Waffles             | 4                   | 0                     | 0                     |
| Strawberry Belgian Waffles  | 4                   | 0                     | 0                     |
| Berry-Berry Belgian Waffles | 4                   | 0                     | 0                     |
| French Toast                | 4                   | 0                     | 0                     |
| Homestyle Breakfast         | 4                   | 0                     | 0                     |
| waffles                     | 1                   | 0                     | 0                     |
| belgian                     | 1                   | 0                     | 0                     |
| strawberries                | 2                   | 0                     | 0                     |
| berries                     | 2                   | 0                     | 0                     |
| french                      | 1                   | 0                     | 0                     |
| toast                       | 1                   | 0                     | 0                     |
| breakfast                   | 1                   | 0                     | 0                     |
| egg                         | 1                   | 0                     | 0                     |
| eggs                        | 1                   | 0                     | 0                     |
| bacon                       | 1                   | 0                     | 0                     |
| sausage                     | 1                   | 0                     | 0                     |
| two                         | 1                   | 0                     | 0                     |
| cream                       | 1                   | 0                     | 0                     |
| *                           | 0                   | 0                     | 0                     |
| null                        | 0                   | 0                     | 0                     |
+-----------------------------+---------------------+-----------------------+-----------------------+
I think that is kind of cool!

visualizing edit distance

Last time we implemented edit distance in BKO, and gave a couple of simple examples. Today I just want to visualize that.

Recall from last time:
-- Levenshtein distance:
sa: insert[g,6] substitute[i,e,4] substitute[s,k,0] |kitten>
|sitting>

-- LCS distance:
sa: insert[g,6] insert[i,4] delete[e,4] insert[s,0] delete[k,0] |kitten>
|sitting>
First, we need a little bit of work to convert this to a pretty graph. First, in the console:
  context visualizing edit distance
  op1 |kitten> => substitute[s,k,0] |_self>
  op2 substitute[s,k,0] |kitten> => substitute[i,e,4] |_self>
  op3 substitute[i,e,4] substitute[s,k,0] |kitten> => insert[g,6] |_self>

  op4 |kitten> => delete[k,0] |_self>
  op5 op4 |kitten> => insert[s,0] |_self>
  op6 op5 op4 |kitten> => delete[e,4] |_self>
  op7 op6 op5 op4 |kitten> => insert[i,4] |_self>
  op8 op7 op6 op5 op4 |kitten> => insert[g,6] |_self>
Now, see what we have:
sa: dump
----------------------------------------
|context> => |context: visualizing edit distance>

op1 |kitten> => |sitten>
op4 |kitten> => |itten>

op2 |sitten> => |sittin>
op6 |sitten> => |sittn>

op3 |sittin> => |sitting>
op8 |sittin> => |sitting>

op5 |itten> => |sitten>

op7 |sittn> => |sittin>
----------------------------------------
sa: save visualizing-edit-distance--raw.sw
sa: q

$ ./sw2dot-v2.py sw-examples/visualizing-edit-distance--raw.sw

$ cat graph-examples/visualizing-edit-distance--raw.dot
digraph g {
"context" -> "visualizing edit distance"
"kitten" -> "sitten" [label="op1",arrowhead=normal]
"kitten" -> "itten" [label="op4",arrowhead=normal]
"sitten" -> "sittin" [label="op2",arrowhead=normal]
"sitten" -> "sittn" [label="op6",arrowhead=normal]
"sittin" -> "sitting" [label="op3",arrowhead=normal]
"sittin" -> "sitting" [label="op8",arrowhead=normal]
"itten" -> "sitten" [label="op5",arrowhead=normal]
"sittn" -> "sittin" [label="op7",arrowhead=normal]
}
Now, we need to tweak the operator labels to this:
$ cat graph-examples/visualizing-edit-distance.dot
digraph g {
"context" -> "visualizing edit distance"
"kitten" -> "sitten" [label="substitute[s,k,0]",arrowhead=normal]
"kitten" -> "itten" [label="delete[k,0]",arrowhead=normal]
"sitten" -> "sittin" [label="substitute[i,e,4]",arrowhead=normal]
"sitten" -> "sittn" [label="delete[e,4]",arrowhead=normal]
"sittin" -> "sitting" [label="insert[g,6]",arrowhead=normal]
"sittin" -> "sitting" [label="insert[g,6]",arrowhead=normal]
"itten" -> "sitten" [label="insert[s,0]",arrowhead=normal]
"sittn" -> "sittin" [label="insert[i,4]",arrowhead=normal]
}
And graph it with graphviz:
Which is a very pretty picture, and neatly shows how operators step through "brain space". And unlike in our previous graphs, these are not literal operators, these are function operators. It also clearly shows how kets map to nodes, and operators to links between nodes.

And a brief comment. I wonder if we want to write some code to auto-map op-sequences to pretty graphs? How easy would it be, and would there be enough use for it? Don't know yet.

Thursday, 17 December 2015

edit distance in BKO

I've been meaning to do this one for a long time now! Finally got around to it today. Not very hard. So, start with the wikipedia page. Now, we need to implement these 3 operators:
    Insertion of a single symbol. If a = uv, then inserting the symbol x produces uxv. This can also be denoted ε→x, using ε to denote the empty string.
    Deletion of a single symbol changes uxv to uv (x→ε).
    Substitution of a single symbol x for a symbol y ≠ x changes uxv to uyv (x→y). 
A few lines of python, and now we can reproduce the example on the wikipage:
The Levenshtein distance between "kitten" and "sitting" is 3. A minimal edit script that transforms the former into the latter is:

    kitten → sitten (substitution of "s" for "k")
    sitten → sittin (substitution of "i" for "e")
    sittin → sitting (insertion of "g" at the end).

LCS distance (insertions and deletions only) gives a different distance and minimal edit script:

    delete k at 0
    insert s at 0
    delete e at 4
    insert i at 4
    insert g at 6

for a total cost/distance of 5 operations.
And now reproduce that example in BKO:
-- Levenshtein distance:
sa: insert[g,6] substitute[i,e,4] substitute[s,k,0] |kitten>
|sitting>

-- LCS distance:
sa: insert[g,6] insert[i,4] delete[e,4] insert[s,0] delete[k,0] |kitten>
|sitting>
And now a couple of comments. First, it seems BKO operators are a natural way to represent these text operators. The second is that the number of operators from starting superposition (in the above example, kets), to the final one seems to form a natural kind of distance metric. This being general, not just for the above 3 operators, but all operators in our project. For example, when you say something is a deep thought, in BKO that would correspond to a very long op sequence from starting facts. And related to that, the brain must be doing something interesting, because for a computer, finding the exact op sequence that matches starting point to desired destination is vastly expensive big O wise. How the brain seems to do this efficiently, I don't know. I mean, it is an extreme example, but consider the 100 page proof of Fermat's last theorem. If we convert that to a big op sequence, naive search to find it would be impossible. I guess humans must divide the problem into smaller problems which require smaller op sequences to find, but still it is rather amazing!

And oh yeah, I think eventually we will find a natural way to encode mathematics using the BKO structure. For example a proof is just an operator (itself constructed from an op sequence) from one superposition (in this case starting axioms and knowledge) to a desired end superposition. And math objects such as metrics or groups correspond to particular network structures. And possibly homomorphisms are maps between objects with similar network structures.

Another thing I should mention is I'm not a big fan of always using edit distance to measure similarity of two strings. Sure, seems to work great for spell check, which so far I can't reproduce well using my simm. But for longer text I prefer my similarity metric. I guess the best link I can give is to this blog post, and this code.

BTW, here was my attempt to use similar[op] for spell check:
sa: load common-English-words.sw
sa: word2ngram-op |*> #=> letter-ngrams[1,2,3] |_self>
sa: map[word2ngram-op,word2ngram] list-of |common English words>
sa: map[word2ngram-op,word2ngram] |elefant>
sa: table[word,coeff] select[1,30] 100 self-similar[word2ngram] |elefant>
+-----------+--------+
| word      | coeff  |
+-----------+--------+
| elefant   | 100.0  |
| elegant   | 66.667 |
| mantelet  | 57.937 |
| elephant  | 57.143 |
| relevant  | 57.143 |
| fantail   | 55.556 |
| infante   | 55.556 |
| teleran   | 55.556 |
| leant     | 52.778 |
| inelegant | 51.389 |
| infantile | 51.389 |
| antler    | 51.111 |
| cantle    | 51.111 |
| levant    | 51.111 |
| mantel    | 51.111 |
| mantle    | 51.111 |
| anele     | 50.0   |
| antefix   | 50.0   |
| defiant   | 50.0   |
| element   | 50.0   |
| fantasm   | 50.0   |
| fantast   | 50.0   |
| fantasy   | 50.0   |
| fantom    | 50.0   |
| gantlet   | 50.0   |
| infant    | 50.0   |
| infanta   | 50.0   |
| pantile   | 50.0   |
| relent    | 50.0   |
| reliant   | 50.0   |
+-----------+--------+
So sort of works. But we have things in there like "mantelet" that has a high match because of "ele" and "ant". This is from the 3-grams, and the fact that we have no real ordering info. So "ele" + "ant" is just as similar as "ant" + "ele". I guess an improvement is not to run the similar[op] on ngrams, but first convert letters into how they are pronounced. And then run similar[op] on that. I don't know the easiest way to do that.

BTW, here is how I made the "common-English-words.sw" file:
-- download data from here: http://icon.shef.ac.uk/Moby/mwords.html
-- then run this script:
$ ./list-to-sp.sh "list-of |common English words> => " 74550com.mon > common-English-words.sw
Update: ahh... one definition of intelligence is the speed with which an agent finds the op sequence that maps from the current state (superposition) to the desired end state (superposition). Especially for the case of non-trivial op sequences. There are other possible definitions. eg, the speed with which an agent finds a good internal representation (ie a well constructed network) for a concept.

BTW, a comment on "well constructed network". This is probably the difference between rote learning a concept (which corresponds to a poorly constructed network), and having a deep understanding of a concept.

Tuesday, 15 December 2015

softmax and log

A couple of simple ones. Softmax and log.

Here is the python:
  def softmax(self):
    result = copy.deepcopy(self)
    the_sum = sum(math.exp(x.value) for x in result.data)
    if the_sum > 0:
      for x in result.data:
        x.value = math.exp(x.value)/the_sum  
    return result

def log(x,t=None):
  if x <= 0:
    return 0
  if t == None:
    return math.log(x)       # default is base e, ie natural logarithm
  return math.log(x,t)       # choose another base
Now, putting them to use:
sa: softmax 10|x>
|x>

sa: softmax (10|x> + 5|y> + 30|z> + |u> + 0.5|v>)
0.0|x> + 0.0|y> + 1.0|z> + 0.0|u> + 0.0|v>

sa: softmax (20|x> + 25|y>)
0.007|x> + 0.993|y>

sa: log |x>
0|x>

-- default is base e, so log(e) = 1.
sa: log 2.71828 |x>
1.0|x>

sa: log[2] 128|x>
7|x>

sa: log[10] (5|a> + 10|b> + 100|c> + 375|d> + 123456|e>)
0.699|a> + |b> + 2|c> + 2.574|d> + 5.092|e>

Monday, 14 December 2015

spreading activation in BKO

Another brief comparison. This time looking at spreading activation, and encoding that in BKO. I'm not going to give it much thought. Just quick and dirty.

This image is on the wikipage:
And has this caption:

In this example, spreading activation originated at node 1 which has an initial activation value of 1.0 (100%). Each link has the same weight value of 0.9. The decay factor was 0.85. Four cycles of spreading activation have occurred. Color hue and saturation indicate different activation values.

The key things to note are link strength is 0.9 and decay factor is 0.85. This produces this BKO:
op |node 1> => 0.9|node 2>
op |node 2> => 0.9|node 3>
op |node 3> => 0.9|node 4> + 0.9|node 11>
op |node 11> => 0.9|node 12>
op |node 12> => 0.9|node 13>
op |node 13> => 0.9|node 14>
op |node 14> => 0.9|node 15>
op |node 15> => 0.9|node 16>
op |node 4> => 0.9|node 5>
op |node 5> => 0.9|node 6>
op |node 6> => 0.9|node 7>
op |node 7> => 0.9|node 8>
op |node 8> => 0.9|node 9>
op |node 9> => 0.9|node 10>
decay-factor |*> #=> 0.85 |_self>
Now, let's "spread our activation":
sa: decay-factor op 100 |node 1>
76.5|node 2>

sa: decay-factor op decay-factor op 100 |node 1>
58.523|node 3>

sa: decay-factor op decay-factor op decay-factor op 100 |node 1>
44.77|node 4> + 44.77|node 11>

sa: decay-factor op decay-factor op decay-factor op decay-factor op 100 |node 1>
34.249|node 5> + 34.249|node 12>
Which nicely reproduces the percentages in the above graph.
Now, we can tidy it to this:
-- define a merged decay-factor and op operator:
sa: decay-factor-op |*> #=> decay-factor op |_self>

-- short cut for: (1 + decay-factor-op + decay-factor-op^2 + decay-factor-op^3 + decay-factor-op^4) 100 |node 1>
sa: exp[decay-factor-op,4] 100 |node 1>
100|node 1> + 76.5|node 2> + 58.523|node 3> + 44.77|node 4> + 44.77|node 11> + 34.249|node 5> + 34.249|node 12>
That is enough for now.

Update: Now with the magic of tables, show the activation spread through the entire network:
sa: decay-factor-op |*> #=> decay-factor op |_self>
sa: table[node,coeff] exp-max[decay-factor-op] 100 |node 1>
+---------+--------+
| node    | coeff  |
+---------+--------+
| node 1  | 100    |
| node 2  | 76.5   |
| node 3  | 58.523 |
| node 4  | 44.77  |
| node 11 | 44.77  |
| node 5  | 34.249 |
| node 12 | 34.249 |
| node 6  | 26.2   |
| node 13 | 26.2   |
| node 7  | 20.043 |
| node 14 | 20.043 |
| node 8  | 15.333 |
| node 15 | 15.333 |
| node 9  | 11.73  |
| node 16 | 11.73  |
| node 10 | 8.973  |
+---------+--------+
Now a tweak. The signal drops to zero if it is below 20% activation:
sa: table[node,coeff] threshold-filter[20] exp-max[decay-factor-op] 100 |node 1>
+---------+--------+
| node    | coeff  |
+---------+--------+
| node 1  | 100    |
| node 2  | 76.5   |
| node 3  | 58.523 |
| node 4  | 44.77  |
| node 11 | 44.77  |
| node 5  | 34.249 |
| node 12 | 34.249 |
| node 6  | 26.2   |
| node 13 | 26.2   |
| node 7  | 20.043 |
| node 14 | 20.043 |
| node 8  | 0      |
| node 15 | 0      |
| node 9  | 0      |
| node 16 | 0      |
| node 10 | 0      |
+---------+--------+
Anyway, all simple enough.

Update: at this stage we have more than proved we can represent most things in BKO (sp-learn rules are currently an exception, waiting for me to finish the parsely implementation of extract-compound-superposition). We are now at the stage of finding ways to learn knowledge with minimal input from a human.

semantic networks in BKO

Reading over on wikipedia about semantic networks. Thought I would give a brief comparison with BKO.

Let's start with this LISP:
(defun *database* ()
'((canary  (is-a bird)
               (color yellow)
               (size small))
   (penguin (is-a bird)
                  (movement swim))
   (bird    (is-a vertebrate)
               (has-part wings)
               (reproduction egg-laying))))
Now in BKO:
----------------------------------------
|context> => |context: semantic network>

is-a |canary> => |bird>
color |canary> => |yellow>
size |canary> => |small>

is-a |penguin> => |bird>
movement |penguin> => |swim>

is-a |bird> => |vertebrate>
has-part |bird> => |wings>
reproduction |bird> => |egg-laying>
----------------------------------------
Anyway, I obviously prefer my notation. For one it is uniform, ie all in form OP KET => KET. And unlike LISP, the grep of any valid sw file, is itself a valid sw file. A small thing, but sometimes useful. eg, if you have a big file and you only need a subset of the operators, using grep you can shrink it to a more manageable file size. The other thing is that in BKO we can effectively have a list on the right hand side (ie a superposition), and further, associate floats with each element in that list. Presumably this is harder in LISP.

Next, the wikipage has this image:
So, let's cast this to BKO:
----------------------------------------
|context> => |context: semantic network example>

has |Mammal> => |Vertebra>
is-an |Mammal> => |Animal>

is-a |Cat> => |Mammal>
has |Cat> => |Fur>

is-a |Bear> => |Mammal>
has |Bear> => |Fur>

is-a |Whale> => |Mammal>
lives-in |Whale> => |Water>

is-an |Fish> => |Animal>
lives-in |Fish> => |Water>
----------------------------------------
And then graphviz this sw we get:

one way to handle URI's in BKO

Pretty much all semantic web work is obsessed with URI's. Me, not so much. I think they are ugly, and there are possibly better ways to handle it. eg, for a given context, give a source URL, and in that page define the URI's. Anyway, today one way to auto-generate URI's in BKO:
-- load some data:
sa: load fred-sam-friends.sw

-- define our URI operators:
-- first, the op URI operator:
sa: URI |op: *> #=> merge-labels(|URI: http://example.com/example-operator-ontology#> + extract-value |_self>)
-- the general URI operator:
sa: URI |*> #=> merge-labels(|URI: http://example.com/example-ontology#> + |_self>)
Now, see what we have:
sa: URI |op: friends>
|URI: http://example.com/example-operator-ontology#friends>

sa: URI |Fred>
|URI: http://example.com/example-ontology#Fred>

sa: URI friends |Fred>
|URI: http://example.com/example-ontology#Jack> + |URI: http://example.com/example-ontology#Harry> + |URI: http://example.com/example-ontology#Ed> + |URI: http://example.com/example-ontology#Mary> + |URI: http://example.com/example-ontology#Rob> + |URI: http://example.com/example-ontology#Patrick> + |URI: http://example.com/example-ontology#Emma> + |URI: http://example.com/example-ontology#Charlie>
I guess that is it. Just note, this is probably not my final word on this topic. I really need to give it more thinking time.

maybe we don't need projections?

Currently my unfinished parser can't handle projections, or bra's or a bunch of other stuff. Yeah, I will get to it eventually. But today a quick example showing maybe we don't need projections?

Consider this list:
the |list> => |number: 137> + |furniture: chair> + |animal: frog> + |furniture: table> + |number: 5573>
The idea was we could filter this down to numbers using: |_pself><number: *| and furniture using |_pself><furniture: *|
But, maybe we don't need that. Let me show you. First define these operators:
number-filter |*> #=> |>
furniture-filter |*> #=> |>
animal-filter |*> #=> |>
animal-number-filter |*> #=> |>

number-filter |number: *> #=> |_self>
animal-number-filter |number: *> #=> |_self>

furniture-filter |furniture: *> #=> |_self>

animal-filter |animal: *> #=> |_self>
animal-number-filter |animal: *> #=> |_self>
Now, put them to use:
sa: number-filter the |list>
|number: 137> + |number: 5573>

sa: furniture-filter the |list>
|furniture: chair> + |furniture: table>

sa: animal-filter the |list>
|animal: frog>

sa: animal-number-filter the |list>
|number: 137> + |animal: frog> + |number: 5573>
I don't yet have a use for this, but I'm pretty sure it will be useful eventually.

Update: if we did have projections, this is how we would define our filters:
number-filter |*> #=> |_pself><number: *||_self>
furniture-filter |*> #=> |_pself><furniture: *||_self>
animal-filter |*> #=> |_pself><animal: *||_self>
animal-number-filter |*> #=> |_pself><animal: *||_self> + |_pself><number: *||_self>
Update: Just an extra thing that would be fun:
-- define our operator:
sa: how-many-numbers-in |*> #=> how-many number-filter |_self>

-- try it out:
sa: how-many-numbers-in the |list>
2|number: 1> + 3|number: 0>
Which is not the answer you might expect! The reason is that our operator is linear. Let me expand that to show more clearly what I mean:
how-many-numbers-in the |list>
== how-many-numbers-in (|number: 137> + |furniture: chair> + |animal: frog> + |furniture: table> + |number: 5573>)
== how-many-numbers-in |number: 137> + how-many-numbers-in |furniture: chair> + how-many-numbers-in |animal: frog> + how-many-numbers-in |furniture: table> + how-many-numbers-in |number: 5573>
== |number: 1> + |number: 0> + |number: 0> + |number: 0> + |number: 1>
== 2|number: 1> + 3|number: 0>
Now, for it to work the way you might expect, then we need learn-sp rules. And then something like:
sa: how-many-numbers-in (*) #=> how-many number-filter |_self>
sa: how-many-numbers-in the |list>
Which should give the desired result of |number: 2>

the easy way to make a big binary tree

A big binary tree would be a bit of work to define fully by hand. So in this short post, an example of how to build one easily.

The BKO:
sa: context bigger binary tree
sa: child |*> #=> left |_self> + right |_self>
sa: left-op |*> #=> merge-labels(|_self> + |0>)
sa: right-op |*> #=> merge-labels(|_self> + |1>)
sa: left |x> => |0>
sa: right |x> => |1>
sa: left |0> => |00>
sa: right |0> => |01>
sa: left |1> => |10>
sa: right |1> => |11>
That gives us a seed tree, now we can grow it rapidly. First note the results of applying child^k to |x>:
sa: child |x>
|0> + |1>

sa: child^2 |x>
|00> + |01> + |10> + |11>
Now, we use this to grow the tree!
  map[left-op,left] child^2 |x>
  map[right-op,right] child^2 |x>

  map[left-op,left] child^3 |x>
  map[right-op,right] child^3 |x>

  map[left-op,left] child^4 |x>
  map[right-op,right] child^4 |x>

  map[left-op,left] child^5 |x>
  map[right-op,right] child^5 |x>

  map[left-op,left] child^6 |x>
  map[right-op,right] child^6 |x>
And now we are done. And it is trivial to make even bigger trees using the same method.
Here is the result:
sa: dump
----------------------------------------
|context> => |context: bigger binary tree>

child |*> #=> left |_self> + right |_self>
left-op |*> #=> merge-labels(|0> + |_self>)
right-op |*> #=> merge-labels(|1> + |_self>)

child |*> #=> left |_self> + right |_self>
left-op |*> #=> merge-labels(|_self> + |0>)
right-op |*> #=> merge-labels(|_self> + |1>)

left |x> => |0>
right |x> => |1>

left |0> => |00>
right |0> => |01>

left |1> => |10>
right |1> => |11>

left |00> => |000>
right |00> => |001>

left |01> => |010>
right |01> => |011>

left |10> => |100>
right |10> => |101>

left |11> => |110>
right |11> => |111>

left |000> => |0000>
right |000> => |0001>

left |001> => |0010>
right |001> => |0011>

left |010> => |0100>
right |010> => |0101>

left |011> => |0110>
right |011> => |0111>

left |100> => |1000>
right |100> => |1001>

left |101> => |1010>
right |101> => |1011>

left |110> => |1100>
right |110> => |1101>

left |111> => |1110>
right |111> => |1111>

left |0000> => |00000>
right |0000> => |00001>

left |0001> => |00010>
right |0001> => |00011>

left |0010> => |00100>
right |0010> => |00101>

left |0011> => |00110>
right |0011> => |00111>

left |0100> => |01000>
right |0100> => |01001>

left |0101> => |01010>
right |0101> => |01011>

left |0110> => |01100>
right |0110> => |01101>

...
And here is the picture:

a brief look at sum of prime factors

OK. A fun one today. Well, I think it is fun, a mathematician would call it trivial. Sum of prime factors. Way back I called these things strange-integers, and they served as an early test of my code. Simply enough define:
strange-int[x] = the sum of the prime factors of x.

Say r has prime factorisation:
r = p1^n1 * p2^n2 * p3^n3 * p4^n4 * ...
Then strange-int[r] = p1*n1 + p2*n2 + p3*n3 + p4*n4 + ...
It has these properties:
strange-int[p] = p if p is prime, or p = 4
strange-int[p] < p otherwise
This has the effect that we can form a tree of integers (for the impatient, here is an image of that tree), where each application of strange-int[] steps one step closer to a final prime.

Here are the first twenty:
-- we need this due to a quirk of my code. 
-- where the strange-int on the right hand side is a function-operator in my functions code.
sa: strange-int |*> #=> strange-int |_self>
sa: table[number,strange-int] range(|number: 2>,|number: 20>)
+--------+-------------+
| number | strange-int |
+--------+-------------+
| 2      | 2           |
| 3      | 3           |
| 4      | 4           |
| 5      | 5           |
| 6      | 5           |
| 7      | 7           |
| 8      | 6           |
| 9      | 6           |
| 10     | 7           |
| 11     | 11          |
| 12     | 7           |
| 13     | 13          |
| 14     | 9           |
| 15     | 8           |
| 16     | 8           |
| 17     | 17          |
| 18     | 8           |
| 19     | 19          |
| 20     | 9           |
+--------+-------------+
Next we can take a look using the strange-int-list operator. This maps an integer to a list of integers down to the final prime. Here are the first 30:
sa: strange-int-list |*> #=> strange-int-list |_self>
sa: how-long-is-strange-int-list |*> #=> how-many strange-int-list |_self>
sa: table[number,strange-int,strange-int-list,how-long-is-strange-int-list] range(|number: 2>,|number: 30>)
+--------+-------------+------------------+------------------------------+
| number | strange-int | strange-int-list | how-long-is-strange-int-list |
+--------+-------------+------------------+------------------------------+
| 2      | 2           | 2                | 1                            |
| 3      | 3           | 3                | 1                            |
| 4      | 4           | 4                | 1                            |
| 5      | 5           | 5                | 1                            |
| 6      | 5           | 6, 5             | 2                            |
| 7      | 7           | 7                | 1                            |
| 8      | 6           | 8, 6, 5          | 3                            |
| 9      | 6           | 9, 6, 5          | 3                            |
| 10     | 7           | 10, 7            | 2                            |
| 11     | 11          | 11               | 1                            |
| 12     | 7           | 12, 7            | 2                            |
| 13     | 13          | 13               | 1                            |
| 14     | 9           | 14, 9, 6, 5      | 4                            |
| 15     | 8           | 15, 8, 6, 5      | 4                            |
| 16     | 8           | 16, 8, 6, 5      | 4                            |
| 17     | 17          | 17               | 1                            |
| 18     | 8           | 18, 8, 6, 5      | 4                            |
| 19     | 19          | 19               | 1                            |
| 20     | 9           | 20, 9, 6, 5      | 4                            |
| 21     | 10          | 21, 10, 7        | 3                            |
| 22     | 13          | 22, 13           | 2                            |
| 23     | 23          | 23               | 1                            |
| 24     | 9           | 24, 9, 6, 5      | 4                            |
| 25     | 10          | 25, 10, 7        | 3                            |
| 26     | 15          | 26, 15, 8, 6, 5  | 5                            |
| 27     | 9           | 27, 9, 6, 5      | 4                            |
| 28     | 11          | 28, 11           | 2                            |
| 29     | 29          | 29               | 1                            |
| 30     | 10          | 30, 10, 7        | 3                            |
+--------+-------------+------------------+------------------------------+
Now, lets sort by strange-int-list length, and find the top 100 of those in the first 100,000 integers.
sa: strange-int |*> #=> strange-int |_self>
sa: strange-int-list |*> #=> strange-int-list |_self>
sa: length-of-strange-int-list |*> #=> how-many strange-int-list |_self>
sa: table[number,strange-int,strange-int-list,length-of-strange-int-list] select[1,100] reverse sort-by[length-of-strange-int-list] range(|number: 2>,|number: 100000>)
+--------+-------------+---------------------------------------------------------+----------------------------+
| number | strange-int | strange-int-list                                        | length-of-strange-int-list |
+--------+-------------+---------------------------------------------------------+----------------------------+
| 55694  | 27849       | 55694, 27849, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5 | 12                         |
| 27933  | 9314        | 27933, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5  | 12                         |
| 99895  | 19984       | 99895, 19984, 1257, 422, 213, 74, 39, 16, 8, 6, 5       | 11                         |
| 97629  | 4659        | 97629, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5        | 11                         |
| 97533  | 10843       | 97533, 10843, 1556, 393, 134, 69, 26, 15, 8, 6, 5       | 11                         |
| 92915  | 18588       | 92915, 18588, 1556, 393, 134, 69, 26, 15, 8, 6, 5       | 11                         |
| 90177  | 30062       | 90177, 30062, 15033, 5014, 134, 69, 26, 15, 8, 6, 5     | 11                         |
| 86696  | 10843       | 86696, 10843, 1556, 393, 134, 69, 26, 15, 8, 6, 5       | 11                         |
| 86662  | 43333       | 86662, 43333, 2566, 1285, 262, 133, 26, 15, 8, 6, 5     | 11                         |
| 84934  | 42469       | 84934, 42469, 6074, 3039, 1016, 133, 26, 15, 8, 6, 5    | 11                         |
| 83718  | 4659        | 83718, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5        | 11                         |
| 74924  | 18735       | 74924, 18735, 1257, 422, 213, 74, 39, 16, 8, 6, 5       | 11                         |
| 74416  | 4659        | 74416, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5        | 11                         |
| 69765  | 4659        | 69765, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5        | 11                         |
| 68653  | 5294        | 68653, 5294, 2649, 886, 445, 94, 49, 14, 9, 6, 5        | 11                         |
| 55686  | 9286        | 55686, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5        | 11                         |
| 46405  | 9286        | 46405, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5        | 11                         |
| 46142  | 23073       | 46142, 23073, 7694, 3849, 1286, 645, 51, 20, 9, 6, 5    | 11                         |
| 36398  | 18201       | 36398, 18201, 6070, 614, 309, 106, 55, 16, 8, 6, 5      | 11                         |
| 30993  | 10334       | 30993, 10334, 5169, 1726, 865, 178, 91, 20, 9, 6, 5     | 11                         |
| 27849  | 9286        | 27849, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5        | 11                         |
| 9314   | 4659        | 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5         | 11                         |
| 99853  | 7694        | 99853, 7694, 3849, 1286, 645, 51, 20, 9, 6, 5           | 10                         |
| 99763  | 1556        | 99763, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 10                         |
| 99482  | 49743       | 99482, 49743, 5533, 514, 259, 44, 15, 8, 6, 5           | 10                         |
| 98422  | 49213       | 98422, 49213, 1726, 865, 178, 91, 20, 9, 6, 5           | 10                         |
| 98386  | 49195       | 98386, 49195, 9844, 134, 69, 26, 15, 8, 6, 5            | 10                         |
| 98284  | 24575       | 98284, 24575, 993, 334, 169, 26, 15, 8, 6, 5            | 10                         |
| 98214  | 16374       | 98214, 16374, 2734, 1369, 74, 39, 16, 8, 6, 5           | 10                         |
| 98151  | 32720       | 98151, 32720, 422, 213, 74, 39, 16, 8, 6, 5             | 10                         |
| 97618  | 48811       | 97618, 48811, 393, 134, 69, 26, 15, 8, 6, 5             | 10                         |
| 97209  | 1556        | 97209, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 10                         |
| 96523  | 13796       | 96523, 13796, 3453, 1154, 579, 196, 18, 8, 6, 5         | 10                         |
| 96467  | 13788       | 96467, 13788, 393, 134, 69, 26, 15, 8, 6, 5             | 10                         |
| 95962  | 47983       | 95962, 47983, 3704, 469, 74, 39, 16, 8, 6, 5            | 10                         |
| 95562  | 5317        | 95562, 5317, 422, 213, 74, 39, 16, 8, 6, 5              | 10                         |
| 94593  | 31534       | 94593, 31534, 15769, 1226, 615, 49, 14, 9, 6, 5         | 10                         |
| 94469  | 5574        | 94469, 5574, 934, 469, 74, 39, 16, 8, 6, 5              | 10                         |
| 94426  | 1556        | 94426, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 10                         |
| 94222  | 47113       | 94222, 47113, 4294, 134, 69, 26, 15, 8, 6, 5            | 10                         |
| 93494  | 46749       | 93494, 46749, 15586, 7795, 1564, 44, 15, 8, 6, 5        | 10                         |
| 93414  | 15574       | 93414, 15574, 614, 309, 106, 55, 16, 8, 6, 5            | 10                         |
| 93382  | 46693       | 93382, 46693, 934, 469, 74, 39, 16, 8, 6, 5             | 10                         |
| 92702  | 46353       | 92702, 46353, 15454, 7729, 190, 26, 15, 8, 6, 5         | 10                         |
| 92654  | 46329       | 92654, 46329, 15446, 7725, 116, 33, 14, 9, 6, 5         | 10                         |
| 92244  | 7694        | 92244, 7694, 3849, 1286, 645, 51, 20, 9, 6, 5           | 10                         |
| 92156  | 23043       | 92156, 23043, 7684, 134, 69, 26, 15, 8, 6, 5            | 10                         |
| 91445  | 18294       | 91445, 18294, 3054, 514, 259, 44, 15, 8, 6, 5           | 10                         |
| 91398  | 15238       | 91398, 15238, 422, 213, 74, 39, 16, 8, 6, 5             | 10                         |
| 91285  | 18262       | 91285, 18262, 422, 213, 74, 39, 16, 8, 6, 5             | 10                         |
| 91213  | 1774        | 91213, 1774, 889, 134, 69, 26, 15, 8, 6, 5              | 10                         |
| 91198  | 45601       | 91198, 45601, 1502, 753, 254, 129, 46, 25, 10, 7        | 10                         |
| 89974  | 44989       | 89974, 44989, 6434, 3219, 69, 26, 15, 8, 6, 5           | 10                         |
| 89702  | 44853       | 89702, 44853, 14954, 7479, 286, 26, 15, 8, 6, 5         | 10                         |
| 89222  | 6382        | 89222, 6382, 3193, 134, 69, 26, 15, 8, 6, 5             | 10                         |
| 89038  | 44521       | 89038, 44521, 422, 213, 74, 39, 16, 8, 6, 5             | 10                         |
| 88870  | 8894        | 88870, 8894, 4449, 1486, 745, 154, 20, 9, 6, 5          | 10                         |
| 87985  | 17602       | 87985, 17602, 692, 177, 62, 33, 14, 9, 6, 5             | 10                         |
| 87938  | 43971       | 87938, 43971, 14660, 742, 62, 33, 14, 9, 6, 5           | 10                         |
| 87554  | 43779       | 87554, 43779, 14596, 134, 69, 26, 15, 8, 6, 5           | 10                         |
| 87222  | 14542       | 87222, 14542, 674, 339, 116, 33, 14, 9, 6, 5            | 10                         |
| 86934  | 14494       | 86934, 14494, 7249, 670, 74, 39, 16, 8, 6, 5            | 10                         |
| 86408  | 1556        | 86408, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 10                         |
| 85983  | 28664       | 85983, 28664, 3589, 134, 69, 26, 15, 8, 6, 5            | 10                         |
| 85686  | 14286       | 85686, 14286, 2386, 1195, 244, 65, 18, 8, 6, 5          | 10                         |
| 85497  | 28502       | 85497, 28502, 14253, 4754, 2379, 77, 18, 8, 6, 5        | 10                         |
| 85317  | 28442       | 85317, 28442, 14223, 445, 94, 49, 14, 9, 6, 5           | 10                         |
| 85299  | 28436       | 85299, 28436, 7113, 2374, 1189, 70, 14, 9, 6, 5         | 10                         |
| 84944  | 5317        | 84944, 5317, 422, 213, 74, 39, 16, 8, 6, 5              | 10                         |
| 84939  | 1257        | 84939, 1257, 422, 213, 74, 39, 16, 8, 6, 5              | 10                         |
| 84684  | 7064        | 84684, 7064, 889, 134, 69, 26, 15, 8, 6, 5              | 10                         |
| 83686  | 41845       | 83686, 41845, 8374, 134, 69, 26, 15, 8, 6, 5            | 10                         |
| 83466  | 4645        | 83466, 4645, 934, 469, 74, 39, 16, 8, 6, 5              | 10                         |
| 83374  | 41689       | 83374, 41689, 934, 469, 74, 39, 16, 8, 6, 5             | 10                         |
| 83282  | 41643       | 83282, 41643, 674, 339, 116, 33, 14, 9, 6, 5            | 10                         |
| 82556  | 20643       | 82556, 20643, 993, 334, 169, 26, 15, 8, 6, 5            | 10                         |
| 81845  | 16374       | 81845, 16374, 2734, 1369, 74, 39, 16, 8, 6, 5           | 10                         |
| 80381  | 11490       | 80381, 11490, 393, 134, 69, 26, 15, 8, 6, 5             | 10                         |
| 80269  | 11474       | 80269, 11474, 5739, 1916, 483, 33, 14, 9, 6, 5          | 10                         |
| 79635  | 5317        | 79635, 5317, 422, 213, 74, 39, 16, 8, 6, 5              | 10                         |
| 79302  | 13222       | 79302, 13222, 614, 309, 106, 55, 16, 8, 6, 5            | 10                         |
| 79146  | 4405        | 79146, 4405, 886, 445, 94, 49, 14, 9, 6, 5              | 10                         |
| 78747  | 26252       | 78747, 26252, 6567, 213, 74, 39, 16, 8, 6, 5            | 10                         |
| 78609  | 26206       | 78609, 26206, 13105, 2626, 116, 33, 14, 9, 6, 5         | 10                         |
| 78502  | 39253       | 78502, 39253, 2326, 1165, 238, 26, 15, 8, 6, 5          | 10                         |
| 78362  | 39183       | 78362, 39183, 393, 134, 69, 26, 15, 8, 6, 5             | 10                         |
| 78038  | 39021       | 78038, 39021, 13010, 1308, 116, 33, 14, 9, 6, 5         | 10                         |
| 77845  | 15574       | 77845, 15574, 614, 309, 106, 55, 16, 8, 6, 5            | 10                         |
| 77709  | 25906       | 77709, 25906, 12955, 2596, 74, 39, 16, 8, 6, 5          | 10                         |
| 77642  | 38823       | 77642, 38823, 12944, 817, 62, 33, 14, 9, 6, 5           | 10                         |
| 77396  | 1774        | 77396, 1774, 889, 134, 69, 26, 15, 8, 6, 5              | 10                         |
| 77391  | 8605        | 77391, 8605, 1726, 865, 178, 91, 20, 9, 6, 5            | 10                         |
| 77289  | 25766       | 77289, 25766, 1006, 505, 106, 55, 16, 8, 6, 5           | 10                         |
| 77109  | 25706       | 77109, 25706, 12855, 865, 178, 91, 20, 9, 6, 5          | 10                         |
| 76870  | 7694        | 76870, 7694, 3849, 1286, 645, 51, 20, 9, 6, 5           | 10                         |
| 76363  | 10916       | 76363, 10916, 2733, 914, 459, 26, 15, 8, 6, 5           | 10                         |
| 76338  | 4249        | 76338, 4249, 614, 309, 106, 55, 16, 8, 6, 5             | 10                         |
| 76165  | 15238       | 76165, 15238, 422, 213, 74, 39, 16, 8, 6, 5             | 10                         |
| 75722  | 37863       | 75722, 37863, 614, 309, 106, 55, 16, 8, 6, 5            | 10                         |
| 74192  | 4645        | 74192, 4645, 934, 469, 74, 39, 16, 8, 6, 5              | 10                         |
+--------+-------------+---------------------------------------------------------+----------------------------+
So it seems, in the first 100,000 integers, 55,694 and 27,933 are in some sense "the least prime", taking 12 steps of strange-int to reach a destination prime. And 91,198 is the only one in the top 100 that has 7 as the final prime instead of 5.

Now, let's upscale to the first 1,000,000 integers (I tried 10,000,000 but python seg-faulted at 1.4 million).
sa: strange-int-list |*> #=> strange-int-list |_self>
sa: length-of-strange-int-list |*> #=> how-many strange-int-list |_self>
sa: table[number,strange-int-list,length-of-strange-int-list] select[1,100] reverse sort-by[length-of-strange-int-list] range(|number: 2>,|number: 1000000>)
+--------+-------------------------------------------------------------------------+----------------------------+
| number | strange-int-list                                                        | length-of-strange-int-list |
+--------+-------------------------------------------------------------------------+----------------------------+
| 334142 | 334142, 167073, 55694, 27849, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5 | 14                         |
| 921327 | 921327, 27933, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5          | 13                         |
| 868022 | 868022, 434013, 144674, 72339, 24116, 6033, 2014, 74, 39, 16, 8, 6, 5   | 13                         |
| 823502 | 823502, 411753, 137254, 5294, 2649, 886, 445, 94, 49, 14, 9, 6, 5       | 13                         |
| 723853 | 723853, 55694, 27849, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5         | 13                         |
| 167073 | 167073, 55694, 27849, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5         | 13                         |
| 999593 | 999593, 142806, 23806, 11905, 2386, 1195, 244, 65, 18, 8, 6, 5          | 12                         |
| 991456 | 991456, 30993, 10334, 5169, 1726, 865, 178, 91, 20, 9, 6, 5             | 12                         |
| 982503 | 982503, 36398, 18201, 6070, 614, 309, 106, 55, 16, 8, 6, 5              | 12                         |
| 959566 | 959566, 479785, 95962, 47983, 3704, 469, 74, 39, 16, 8, 6, 5            | 12                         |
| 945958 | 945958, 36398, 18201, 6070, 614, 309, 106, 55, 16, 8, 6, 5              | 12                         |
| 944206 | 944206, 472105, 94426, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 12                         |
| 929490 | 929490, 30993, 10334, 5169, 1726, 865, 178, 91, 20, 9, 6, 5             | 12                         |
| 922660 | 922660, 46142, 23073, 7694, 3849, 1286, 645, 51, 20, 9, 6, 5            | 12                         |
| 912805 | 912805, 182566, 91285, 18262, 422, 213, 74, 39, 16, 8, 6, 5             | 12                         |
| 904603 | 904603, 129236, 32313, 10774, 5389, 334, 169, 26, 15, 8, 6, 5           | 12                         |
| 896734 | 896734, 448369, 15490, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 12                         |
| 892578 | 892578, 148768, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5               | 12                         |
| 892569 | 892569, 297526, 148765, 29758, 14881, 670, 74, 39, 16, 8, 6, 5          | 12                         |
| 888542 | 888542, 444273, 148094, 74049, 24686, 12345, 831, 280, 18, 8, 6, 5      | 12                         |
| 887613 | 887613, 295874, 147939, 4497, 1502, 753, 254, 129, 46, 25, 10, 7        | 12                         |
| 882202 | 882202, 441103, 33944, 4249, 614, 309, 106, 55, 16, 8, 6, 5             | 12                         |
| 873336 | 873336, 36398, 18201, 6070, 614, 309, 106, 55, 16, 8, 6, 5              | 12                         |
| 866890 | 866890, 86696, 10843, 1556, 393, 134, 69, 26, 15, 8, 6, 5               | 12                         |
| 864627 | 864627, 288212, 72057, 24022, 12013, 334, 169, 26, 15, 8, 6, 5          | 12                         |
| 837277 | 837277, 119618, 59811, 19940, 1006, 505, 106, 55, 16, 8, 6, 5           | 12                         |
| 780437 | 780437, 111498, 18588, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 12                         |
| 774575 | 774575, 30993, 10334, 5169, 1726, 865, 178, 91, 20, 9, 6, 5             | 12                         |
| 745717 | 745717, 106538, 53271, 1982, 993, 334, 169, 26, 15, 8, 6, 5             | 12                         |
| 743815 | 743815, 148768, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5               | 12                         |
| 735006 | 735006, 122506, 61255, 12256, 393, 134, 69, 26, 15, 8, 6, 5             | 12                         |
| 727780 | 727780, 36398, 18201, 6070, 614, 309, 106, 55, 16, 8, 6, 5              | 12                         |
| 723749 | 723749, 55686, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5                | 12                         |
| 719214 | 719214, 119874, 19984, 1257, 422, 213, 74, 39, 16, 8, 6, 5              | 12                         |
| 697062 | 697062, 116182, 5294, 2649, 886, 445, 94, 49, 14, 9, 6, 5               | 12                         |
| 688958 | 688958, 344481, 114830, 11490, 393, 134, 69, 26, 15, 8, 6, 5            | 12                         |
| 674593 | 674593, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                 | 12                         |
| 668958 | 668958, 111498, 18588, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 12                         |
| 650643 | 650643, 30993, 10334, 5169, 1726, 865, 178, 91, 20, 9, 6, 5             | 12                         |
| 645862 | 645862, 46142, 23073, 7694, 3849, 1286, 645, 51, 20, 9, 6, 5            | 12                         |
| 638782 | 638782, 319393, 10334, 5169, 1726, 865, 178, 91, 20, 9, 6, 5            | 12                         |
| 638422 | 638422, 319213, 5294, 2649, 886, 445, 94, 49, 14, 9, 6, 5               | 12                         |
| 631924 | 631924, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                 | 12                         |
| 613628 | 613628, 153411, 51140, 2566, 1285, 262, 133, 26, 15, 8, 6, 5            | 12                         |
| 612505 | 612505, 122506, 61255, 12256, 393, 134, 69, 26, 15, 8, 6, 5             | 12                         |
| 609218 | 609218, 304611, 101540, 5086, 2545, 514, 259, 44, 15, 8, 6, 5           | 12                         |
| 606823 | 606823, 86696, 10843, 1556, 393, 134, 69, 26, 15, 8, 6, 5               | 12                         |
| 601113 | 601113, 200374, 5294, 2649, 886, 445, 94, 49, 14, 9, 6, 5               | 12                         |
| 599345 | 599345, 119874, 19984, 1257, 422, 213, 74, 39, 16, 8, 6, 5              | 12                         |
| 592684 | 592684, 148175, 5937, 1982, 993, 334, 169, 26, 15, 8, 6, 5              | 12                         |
| 587427 | 587427, 195812, 48957, 16322, 8163, 913, 94, 49, 14, 9, 6, 5            | 12                         |
| 580885 | 580885, 116182, 5294, 2649, 886, 445, 94, 49, 14, 9, 6, 5               | 12                         |
| 575422 | 575422, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                 | 12                         |
| 568983 | 568983, 189664, 5937, 1982, 993, 334, 169, 26, 15, 8, 6, 5              | 12                         |
| 568196 | 568196, 142053, 47354, 23679, 886, 445, 94, 49, 14, 9, 6, 5             | 12                         |
| 557465 | 557465, 111498, 18588, 1556, 393, 134, 69, 26, 15, 8, 6, 5              | 12                         |
| 538414 | 538414, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                 | 12                         |
| 533198 | 533198, 266601, 88870, 8894, 4449, 1486, 745, 154, 20, 9, 6, 5          | 12                         |
| 509446 | 509446, 36398, 18201, 6070, 614, 309, 106, 55, 16, 8, 6, 5              | 12                         |
| 496966 | 496966, 248485, 49702, 24853, 886, 445, 94, 49, 14, 9, 6, 5             | 12                         |
| 471633 | 471633, 157214, 78609, 26206, 13105, 2626, 116, 33, 14, 9, 6, 5         | 12                         |
| 458187 | 458187, 152732, 38187, 4249, 614, 309, 106, 55, 16, 8, 6, 5             | 12                         |
| 446466 | 446466, 74416, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                | 12                         |
| 434013 | 434013, 144674, 72339, 24116, 6033, 2014, 74, 39, 16, 8, 6, 5           | 12                         |
| 424113 | 424113, 141374, 70689, 23566, 11785, 2362, 1183, 33, 14, 9, 6, 5        | 12                         |
| 417591 | 417591, 46405, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5                | 12                         |
| 411753 | 411753, 137254, 5294, 2649, 886, 445, 94, 49, 14, 9, 6, 5               | 12                         |
| 401614 | 401614, 200809, 28694, 14349, 4786, 2395, 484, 26, 15, 8, 6, 5          | 12                         |
| 390914 | 390914, 195459, 5937, 1982, 993, 334, 169, 26, 15, 8, 6, 5              | 12                         |
| 372055 | 372055, 74416, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                | 12                         |
| 371192 | 371192, 46405, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5                | 12                         |
| 367509 | 367509, 122506, 61255, 12256, 393, 134, 69, 26, 15, 8, 6, 5             | 12                         |
| 360692 | 360692, 90177, 30062, 15033, 5014, 134, 69, 26, 15, 8, 6, 5             | 12                         |
| 353134 | 353134, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                 | 12                         |
| 343249 | 343249, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                 | 12                         |
| 334086 | 334086, 55686, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5                | 12                         |
| 306818 | 306818, 153411, 51140, 2566, 1285, 262, 133, 26, 15, 8, 6, 5            | 12                         |
| 287773 | 287773, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                 | 12                         |
| 279044 | 279044, 69765, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                | 12                         |
| 278405 | 278405, 55686, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5                | 12                         |
| 268342 | 268342, 134173, 10334, 5169, 1726, 865, 178, 91, 20, 9, 6, 5            | 12                         |
| 260079 | 260079, 86696, 10843, 1556, 393, 134, 69, 26, 15, 8, 6, 5               | 12                         |
| 223239 | 223239, 74416, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                | 12                         |
| 139526 | 139526, 69765, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                | 12                         |
| 55694  | 55694, 27849, 9286, 4645, 934, 469, 74, 39, 16, 8, 6, 5                 | 12                         |
| 27933  | 27933, 9314, 4659, 1556, 393, 134, 69, 26, 15, 8, 6, 5                  | 12                         |
| 999242 | 999242, 499623, 166544, 1502, 753, 254, 129, 46, 25, 10, 7              | 11                         |
| 998454 | 998454, 166414, 83209, 11894, 334, 169, 26, 15, 8, 6, 5                 | 11                         |
| 995216 | 995216, 62209, 8894, 4449, 1486, 745, 154, 20, 9, 6, 5                  | 11                         |
| 994966 | 994966, 71078, 5086, 2545, 514, 259, 44, 15, 8, 6, 5                    | 11                         |
| 994822 | 994822, 497413, 71066, 35535, 134, 69, 26, 15, 8, 6, 5                  | 11                         |
| 994094 | 994094, 497049, 23679, 886, 445, 94, 49, 14, 9, 6, 5                    | 11                         |
| 993838 | 993838, 496921, 6070, 614, 309, 106, 55, 16, 8, 6, 5                    | 11                         |
| 993189 | 993189, 331066, 165535, 33112, 4145, 834, 144, 14, 9, 6, 5              | 11                         |
| 992778 | 992778, 165468, 13796, 3453, 1154, 579, 196, 18, 8, 6, 5                | 11                         |
| 992202 | 992202, 165372, 13788, 393, 134, 69, 26, 15, 8, 6, 5                    | 11                         |
| 990816 | 990816, 10334, 5169, 1726, 865, 178, 91, 20, 9, 6, 5                    | 11                         |
| 990588 | 990588, 82556, 20643, 993, 334, 169, 26, 15, 8, 6, 5                    | 11                         |
| 989593 | 989593, 89974, 44989, 6434, 3219, 69, 26, 15, 8, 6, 5                   | 11                         |
| 989513 | 989513, 141366, 23566, 11785, 2362, 1183, 33, 14, 9, 6, 5               | 11                         |
+--------+-------------------------------------------------------------------------+----------------------------+
I guess one observation to make here is that length-of-strange-int-list grows rather slowly. And that 334,142 is in some sense the least prime.

Plenty more way's to slice and dice strange-ints. eg, count how many integers map to a given prime. Here is a simple example, making use of strange-int-prime that maps numbers to their primes:
-- show strange-int-prime in use:
sa: strange-int-prime |number: 55694>
|number: 5>
sa: strange-int-prime |number: 91198>
|number: 7>

-- now count the strange-int-primes:
sa: table[number,coeff] strange-int-prime range(|number: 2>,|number: 20>)
+--------+-------+
| number | coeff |
+--------+-------+
| 2      | 1     |
| 3      | 1     |
| 4      | 1     |
| 5      | 9     |
| 7      | 3     |
| 11     | 1     |
| 13     | 1     |
| 17     | 1     |
| 19     | 1     |
+--------+-------+
Now upscale to 100,000 and sort:
sa: table[number,coeff] select[1,100] coeff-sort strange-int-prime range(|number: 2>,|number: 100000>)
+--------+-------+
| number | coeff |
+--------+-------+
| 5      | 27023 |
| 7      | 15753 |
| 13     | 6821  |
| 11     | 6032  |
| 19     | 3837  |
| 17     | 3146  |
| 23     | 2289  |
| 31     | 1497  |
| 29     | 1194  |
| 43     | 1161  |
| 37     | 937   |
| 47     | 792   |
| 41     | 747   |
| 61     | 719   |
| 73     | 658   |
| 53     | 626   |
| 59     | 477   |
| 103    | 463   |
| 109    | 445   |
| 67     | 444   |
| 71     | 444   |
| 83     | 405   |
| 79     | 401   |
| 113    | 354   |
| 89     | 348   |
| 139    | 326   |
| 101    | 325   |
| 107    | 316   |
| 151    | 275   |
| 131    | 247   |
| 97     | 246   |
| 181    | 226   |
| 127    | 218   |
| 137    | 208   |
| 167    | 207   |
| 199    | 207   |
| 149    | 206   |
| 193    | 202   |
| 229    | 190   |
| 173    | 185   |
| 163    | 177   |
| 157    | 175   |
| 197    | 174   |
| 241    | 164   |
| 179    | 157   |
| 191    | 143   |
| 283    | 129   |
| 239    | 127   |
| 271    | 126   |
| 233    | 124   |
| 211    | 121   |
| 257    | 119   |
| 227    | 117   |
| 313    | 116   |
| 281    | 115   |
| 293    | 99    |
| 251    | 97    |
| 263    | 97    |
| 277    | 95    |
| 269    | 94    |
| 317    | 92    |
| 223    | 90    |
| 349    | 86    |
| 383    | 70    |
| 311    | 67    |
| 463    | 66    |
| 307    | 61    |
| 373    | 61    |
| 367    | 60    |
| 421    | 60    |
| 353    | 59    |
| 359    | 58    |
| 401    | 58    |
| 433    | 58    |
| 331    | 56    |
| 523    | 56    |
| 347    | 55    |
| 619    | 55    |
| 397    | 54    |
| 443    | 54    |
| 337    | 53    |
| 389    | 51    |
| 379    | 50    |
| 449    | 50    |
| 467    | 48    |
| 503    | 48    |
| 409    | 46    |
| 457    | 44    |
| 571    | 44    |
| 661    | 44    |
| 431    | 43    |
| 461    | 43    |
| 509    | 42    |
| 601    | 42    |
| 439    | 41    |
| 479    | 41    |
| 617    | 38    |
| 613    | 37    |
| 419    | 35    |
| 491    | 35    |
+--------+-------+
Now, upscale to 500,000:
sa: table[number,coeff] select[1,100] coeff-sort strange-int-prime range(|number: 2>,|number: 500000>)
+--------+--------+
| number | coeff  |
+--------+--------+
| 5      | 133689 |
| 7      | 76847  |
| 13     | 33690  |
| 11     | 29661  |
| 19     | 18500  |
| 17     | 15111  |
| 23     | 11463  |
| 31     | 7730   |
| 29     | 6187   |
| 43     | 5479   |
| 37     | 4444   |
| 47     | 3879   |
| 41     | 3849   |
| 61     | 3503   |
| 73     | 3263   |
| 53     | 3096   |
| 103    | 2308   |
| 67     | 2304   |
| 109    | 2105   |
| 59     | 2097   |
| 71     | 2071   |
| 83     | 1926   |
| 79     | 1925   |
| 113    | 1655   |
| 139    | 1608   |
| 89     | 1607   |
| 107    | 1457   |
| 101    | 1278   |
| 151    | 1155   |
| 97     | 1148   |
| 181    | 1045   |
| 131    | 1022   |
| 199    | 991    |
| 193    | 955    |
| 137    | 903    |
| 229    | 901    |
| 167    | 889    |
| 173    | 852    |
| 157    | 821    |
| 197    | 821    |
| 127    | 795    |
| 163    | 787    |
| 149    | 784    |
| 179    | 771    |
| 241    | 748    |
| 233    | 708    |
| 283    | 686    |
| 191    | 660    |
| 271    | 652    |
| 313    | 650    |
| 281    | 616    |
| 227    | 615    |
| 239    | 591    |
| 263    | 569    |
| 211    | 559    |
| 257    | 558    |
| 251    | 538    |
| 277    | 530    |
| 317    | 516    |
| 269    | 499    |
| 223    | 484    |
| 349    | 467    |
| 293    | 459    |
| 311    | 450    |
| 421    | 412    |
| 463    | 412    |
| 353    | 399    |
| 383    | 397    |
| 359    | 386    |
| 433    | 381    |
| 401    | 375    |
| 307    | 374    |
| 389    | 366    |
| 337    | 359    |
| 373    | 350    |
| 467    | 347    |
| 379    | 346    |
| 619    | 345    |
| 347    | 339    |
| 397    | 330    |
| 331    | 327    |
| 449    | 320    |
| 523    | 316    |
| 367    | 315    |
| 443    | 302    |
| 509    | 298    |
| 461    | 293    |
| 661    | 290    |
| 439    | 288    |
| 419    | 284    |
| 409    | 283    |
| 571    | 272    |
| 601    | 268    |
| 479    | 264    |
| 491    | 263    |
| 431    | 262    |
| 503    | 257    |
| 457    | 256    |
| 643    | 255    |
| 617    | 245    |
+--------+--------+
And I guess we can ask the question, does this ordering of primes (5,7,13,11,19,17,23,31,29,43,37,...) stabilize as n -> infinity? I suspect it just might. OK. I had a closer look with more examples, and it might and it might not. If it does, it would provide a kind of natural ordering of primes. Whatever use that may be.
n from 2 to 100,000 gives this ordering:
5,7,13,11,19,17,23,31,29,43,37,47,41,61,73,53,59,103,109,67,71,83,79,113,89,139,101,107,151,131,97,...

n from 2 to 500,000 gives this ordering:
5,7,13,11,19,17,23,31,29,43,37,47,41,61,73,53,103,67,109,59,71,83,79,113,139,89,107,101,151,97,181,... 

n from 500,000 to 1,000,000 gives this ordering:
5,7,13,11,19,17,23,31,29,43,37,41,47,61,73,53,103,71,109,67,59,83,79,113,139,89,107,101,151,97,181,...

n from 1,000,000 to 1,500,000 gives this ordering:
5,7,13,11,19,17,23,31,29,43,37,47,41,61,73,53,59,103,67,71,109,83,79,113,89,107,139,101,151,181,97,...
Next, we can use strange-int-prime to define an equivalency class:
x is in [p] if strange-int-prime[x] = p
Now, in BKO:
-- find strange-int-primes:
sa: strange-int-prime-op |*> #=> strange-int-prime |_self>
sa: map[strange-int-prime-op,strange-int-prime] range(|number: 2>,|number: 1000>)

-- find inverse-strange-int-primes:
sa: find-inverse[strange-int-prime]

-- find primes:
sa: is-prime-op |*> #=> is-prime |_self>
sa: map[is-prime-op,is-prime] range(|number: 2>,|number: 1000>)

-- find inverse-primes:
sa: find-inverse[is-prime]

-- for display reasons, just want the first 25 inverse-strange-int-primes:
sa: inverse-strange-int-prime-list |*> #=> select[1,25] inverse-strange-int-prime |_self>

-- now our pretty table:
sa: table[prime,inverse-strange-int-prime-list] select[1,75] inverse-is-prime |yes>
+-------+---------------------------------------------------------------------------------------------------------------------------+
| prime | inverse-strange-int-prime-list                                                                                            |
+-------+---------------------------------------------------------------------------------------------------------------------------+
| 2     | 2                                                                                                                         |
| 3     | 3                                                                                                                         |
| 5     | 5, 6, 8, 9, 14, 15, 16, 18, 20, 24, 26, 27, 33, 39, 44, 49, 51, 55, 62, 65, 66, 69, 70, 74, 77                            |
| 7     | 7, 10, 12, 21, 25, 30, 32, 35, 36, 38, 42, 46, 50, 60, 64, 68, 72, 81, 87, 124, 129, 141, 152, 155, 158                   |
| 11    | 11, 28, 40, 45, 48, 54, 86, 111, 115, 138, 164, 187, 215, 218, 226, 249, 258, 266, 287, 319, 329, 338, 380, 391, 407      |
| 13    | 13, 22, 56, 57, 63, 75, 80, 85, 90, 96, 102, 108, 121, 122, 146, 159, 166, 182, 212, 236, 260, 284, 308, 312, 314         |
| 17    | 17, 52, 88, 99, 147, 175, 194, 210, 224, 235, 250, 252, 282, 300, 320, 346, 360, 384, 405, 415, 432, 451, 466, 486, 498   |
| 19    | 19, 34, 93, 104, 117, 145, 165, 174, 176, 198, 245, 253, 289, 294, 303, 326, 350, 356, 420, 448, 452, 494, 500, 502, 504  |
| 23    | 23, 76, 136, 153, 219, 273, 302, 325, 355, 385, 390, 416, 426, 462, 468, 542, 550, 596, 655, 660, 686, 704, 706, 766, 786 |
| 29    | 29, 184, 207, 399, 475, 507, 543, 570, 595, 608, 684, 714, 715, 794, 847, 850, 858, 895                                   |
| 31    | 31, 58, 265, 318, 345, 368, 414, 517, 526, 561, 665, 697, 798, 833, 841, 845, 950                                         |
| 37    | 37, 248, 279, 435, 464, 522, 554, 759, 866, 867                                                                           |
| 41    | 41, 148, 651, 775, 930, 992                                                                                               |
| 43    | 43, 82, 237, 296, 333, 662, 781, 879, 932, 957                                                                            |
| 47    | 47, 172, 328, 369, 734, 777, 835, 925                                                                                     |
| 53    | 53, 376, 423, 842, 903                                                                                                    |
| 59    | 59, 424, 477                                                                                                              |
| 61    | 61, 118, 565, 678, 795, 848, 954                                                                                          |
| 67    | 67, 488, 549, 885, 944                                                                                                    |
| 71    | 71, 268                                                                                                                   |
| 73    | 73, 142, 417, 536, 603, 685, 822                                                                                          |
| 79    | 79, 584, 657                                                                                                              |
| 83    | 83, 316, 939                                                                                                              |
| 89    | 89, 664, 747                                                                                                              |
| 97    | 97                                                                                                                        |
| 101   | 101, 388                                                                                                                  |
| 103   | 103, 202, 597, 776, 873, 985                                                                                              |
| 107   | 107, 412, 808, 909                                                                                                        |
| 109   | 109, 214, 633, 824, 927                                                                                                   |
| 113   | 113, 436, 856, 963                                                                                                        |
| 127   | 127                                                                                                                       |
| 131   | 131, 508                                                                                                                  |
| 137   | 137                                                                                                                       |
| 139   | 139, 274, 813                                                                                                             |
| 149   | 149                                                                                                                       |
| 151   | 151, 298                                                                                                                  |
| 157   | 157                                                                                                                       |
| 163   | 163                                                                                                                       |
| 167   | 167, 652                                                                                                                  |
| 173   | 173                                                                                                                       |
| 179   | 179                                                                                                                       |
| 181   | 181, 358                                                                                                                  |
| 191   | 191                                                                                                                       |
| 193   | 193, 382                                                                                                                  |
| 197   | 197, 772                                                                                                                  |
| 199   | 199, 394                                                                                                                  |
| 211   | 211                                                                                                                       |
| 223   | 223                                                                                                                       |
| 227   | 227, 892                                                                                                                  |
| 229   | 229, 454                                                                                                                  |
| 233   | 233, 916                                                                                                                  |
| 239   | 239                                                                                                                       |
| 241   | 241, 478                                                                                                                  |
| 251   | 251                                                                                                                       |
| 257   | 257                                                                                                                       |
| 263   | 263                                                                                                                       |
| 269   | 269                                                                                                                       |
| 271   | 271, 538                                                                                                                  |
| 277   | 277                                                                                                                       |
| 281   | 281                                                                                                                       |
| 283   | 283, 562                                                                                                                  |
| 293   | 293                                                                                                                       |
| 307   | 307                                                                                                                       |
| 311   | 311                                                                                                                       |
| 313   | 313, 622                                                                                                                  |
| 317   | 317                                                                                                                       |
| 331   | 331                                                                                                                       |
| 337   | 337                                                                                                                       |
| 347   | 347                                                                                                                       |
| 349   | 349, 694                                                                                                                  |
| 353   | 353                                                                                                                       |
| 359   | 359                                                                                                                       |
| 367   | 367                                                                                                                       |
| 373   | 373                                                                                                                       |
| 379   | 379                                                                                                                       |
+-------+---------------------------------------------------------------------------------------------------------------------------+
The interpretation being all elements in the second column are members of the strange-int-prime equivalency class of the prime in the first column.

Finally, let's visualize our sum-of-prime factor tree:
sa: context sum of prime factors
sa: SoPF-op |*> #=> extract-value strange-int merge-labels(|number: > + |_self>)
sa: map[SoPF-op,SoPF] range(|2>,|1000>)
sa: save sum-of-prime-factors.sw
sa: q

$ ./sw2dot-v2.py sw-examples/sum-of-prime-factors.sw
Then open graph-examples/sum-of-prime-factors.dot with graphviz, producing:

NB: the picture is too large to see here, so click on it to see the full, but pretty, tree.

Anyway, the point of this post is not just about strange-ints. It is more about giving some examples of how you can slice and dice knowledge using the knowledge engine.

Friday, 4 December 2015

update on visualizing sw files

I had a bit more of a read of the DOT manual, and found a neater way to write my dot files. So, here is the new code.

Now, a couple of examples:

First, Fibonacci numbers, with some saved examples.
The sw:
|context> => |context: Fibonacci>

fib |0> => |1>
fib |1> => |1>

n-1 |*> #=> arithmetic(|_self>,|->,|1>)
n-2 |*> #=> arithmetic(|_self>,|->,|2>)
fib |*> #=> arithmetic( fib n-1 |_self>, |+>, fib n-2 |_self>)
fib-ratio |*> #=> arithmetic( fib |_self> , |/>, fib n-1 |_self> )

fib |2> => |2>
fib |3> => |3>
fib |4> => |5>
fib |5> => |8>
fib |6> => |13>
fib |7> => |21>
fib |8> => |34>
fib |9> => |55>
fib |10> => |89>
fib |11> => |144>
fib |12> => |233>
fib |13> => |377>
fib |14> => |610>
fib |15> => |987>
fib |16> => |1597>
fib |17> => |2584>
fib |18> => |4181>
fib |19> => |6765>
fib |20> => |10946>
fib |21> => |17711>
fib |22> => |28657>
fib |23> => |46368>
fib |24> => |75025>
fib |25> => |121393>
fib |26> => |196418>
fib |27> => |317811>
fib |28> => |514229>
fib |29> => |832040>
fib |30> => |1346269>
And the dot:
digraph g {
"context" -> "Fibonacci"
"0" -> "1" [label="fib",arrowhead=normal]
"1" -> "1" [label="fib",arrowhead=normal]
"*" -> "arithmetic(|_self>,|->,|1>)" [label="n-1",arrowhead=box]
"*" -> "arithmetic(|_self>,|->,|2>)" [label="n-2",arrowhead=box]
"*" -> "arithmetic( fib n-1 |_self>, |+>, fib n-2 |_self>)" [label="fib",arrowhead=box]
"*" -> "arithmetic( fib |_self> , |/>, fib n-1 |_self> )" [label="fib-ratio",arrowhead=box]
"2" -> "2" [label="fib",arrowhead=normal]
"3" -> "3" [label="fib",arrowhead=normal]
"4" -> "5" [label="fib",arrowhead=normal]
"5" -> "8" [label="fib",arrowhead=normal]
"6" -> "13" [label="fib",arrowhead=normal]
"7" -> "21" [label="fib",arrowhead=normal]
"8" -> "34" [label="fib",arrowhead=normal]
"9" -> "55" [label="fib",arrowhead=normal]
"10" -> "89" [label="fib",arrowhead=normal]
"11" -> "144" [label="fib",arrowhead=normal]
"12" -> "233" [label="fib",arrowhead=normal]
"13" -> "377" [label="fib",arrowhead=normal]
"14" -> "610" [label="fib",arrowhead=normal]
"15" -> "987" [label="fib",arrowhead=normal]
"16" -> "1597" [label="fib",arrowhead=normal]
"17" -> "2584" [label="fib",arrowhead=normal]
"18" -> "4181" [label="fib",arrowhead=normal]
"19" -> "6765" [label="fib",arrowhead=normal]
"20" -> "10946" [label="fib",arrowhead=normal]
"21" -> "17711" [label="fib",arrowhead=normal]
"22" -> "28657" [label="fib",arrowhead=normal]
"23" -> "46368" [label="fib",arrowhead=normal]
"24" -> "75025" [label="fib",arrowhead=normal]
"25" -> "121393" [label="fib",arrowhead=normal]
"26" -> "196418" [label="fib",arrowhead=normal]
"27" -> "317811" [label="fib",arrowhead=normal]
"28" -> "514229" [label="fib",arrowhead=normal]
"29" -> "832040" [label="fib",arrowhead=normal]
"30" -> "1346269" [label="fib",arrowhead=normal]
}
 
And now, some plurals:
|context> => |context: learning plurals>

source |context: learning plurals> => |url: http://www.macmillandictionary.com/thesaurus-category/british/irregular-plurals>

plural |word: *> #=> merge-labels(|_self> + |s>)

plural |word: calf> => |word: calves>
plural |word: child> => |word: children>
plural |word: corpus> => |word: corpora>
plural |word: elf> => |word: elves>
plural |word: foot> => |word: feet>
plural |word: goose> => |word: geese>
plural |word: genus> => |word: genera>
plural |word: half> => |word: halves>
plural |word: hoof> => |word: hooves>
plural |word: index> => |word: indices>
plural |word: knife> => |word: knives>
plural |word: leaf> => |word: leaves>
plural |word: life> => |word: lives>
plural |word: loaf> => |word: loaves>
plural |word: matrix> => |word: matrices>
plural |word: medium> => |word: media>
plural |word: man> => |word: men>
plural |word: mouse> => |word: mice>
plural |word: ovum> => |word: ova>
plural |word: ox> => |word: oxen>
plural |word: penny> => |word: pence>
plural |word: person> => |word: people>
plural |word: quantum> => |word: quanta>
plural |word: radius> => |word: radii>
plural |word: scarf> => |word: scarves>
plural |word: self> => |word: selves>
plural |word: serum> => |word: sera>
plural |word: sheaf> => |word: sheaves>
plural |word: shelf> => |word: shelves>
plural |word: sky> => |word: skies>
plural |word: stratum> => |word: strata>
plural |word: tooth> => |word: teeth>
plural |word: testis> => |word: testes>
plural |word: this> => |word: these>
plural |word: that> => |word: those>
plural |word: wife> => |word: wives>
plural |word: wolf> => |word: wolves>
plural |word: woman> => |word: women>
The dot:
digraph g {
"context" -> "learning plurals"
"context: learning plurals" -> "url: http://www.macmillandictionary.com/thesaurus-category/british/irregular-plurals" [label="source",arrowhead=normal]
"word: *" -> "merge-labels(|_self> + |s>)" [label="plural",arrowhead=box]
"word: calf" -> "word: calves" [label="plural",arrowhead=normal]
"word: child" -> "word: children" [label="plural",arrowhead=normal]
"word: corpus" -> "word: corpora" [label="plural",arrowhead=normal]
"word: elf" -> "word: elves" [label="plural",arrowhead=normal]
"word: foot" -> "word: feet" [label="plural",arrowhead=normal]
"word: goose" -> "word: geese" [label="plural",arrowhead=normal]
"word: genus" -> "word: genera" [label="plural",arrowhead=normal]
"word: half" -> "word: halves" [label="plural",arrowhead=normal]
"word: hoof" -> "word: hooves" [label="plural",arrowhead=normal]
"word: index" -> "word: indices" [label="plural",arrowhead=normal]
"word: knife" -> "word: knives" [label="plural",arrowhead=normal]
"word: leaf" -> "word: leaves" [label="plural",arrowhead=normal]
"word: life" -> "word: lives" [label="plural",arrowhead=normal]
"word: loaf" -> "word: loaves" [label="plural",arrowhead=normal]
"word: matrix" -> "word: matrices" [label="plural",arrowhead=normal]
"word: medium" -> "word: media" [label="plural",arrowhead=normal]
"word: man" -> "word: men" [label="plural",arrowhead=normal]
"word: mouse" -> "word: mice" [label="plural",arrowhead=normal]
"word: ovum" -> "word: ova" [label="plural",arrowhead=normal]
"word: ox" -> "word: oxen" [label="plural",arrowhead=normal]
"word: penny" -> "word: pence" [label="plural",arrowhead=normal]
"word: person" -> "word: people" [label="plural",arrowhead=normal]
"word: quantum" -> "word: quanta" [label="plural",arrowhead=normal]
"word: radius" -> "word: radii" [label="plural",arrowhead=normal]
"word: scarf" -> "word: scarves" [label="plural",arrowhead=normal]
"word: self" -> "word: selves" [label="plural",arrowhead=normal]
"word: serum" -> "word: sera" [label="plural",arrowhead=normal]
"word: sheaf" -> "word: sheaves" [label="plural",arrowhead=normal]
"word: shelf" -> "word: shelves" [label="plural",arrowhead=normal]
"word: sky" -> "word: skies" [label="plural",arrowhead=normal]
"word: stratum" -> "word: strata" [label="plural",arrowhead=normal]
"word: tooth" -> "word: teeth" [label="plural",arrowhead=normal]
"word: testis" -> "word: testes" [label="plural",arrowhead=normal]
"word: this" -> "word: these" [label="plural",arrowhead=normal]
"word: that" -> "word: those" [label="plural",arrowhead=normal]
"word: wife" -> "word: wives" [label="plural",arrowhead=normal]
"word: wolf" -> "word: wolves" [label="plural",arrowhead=normal]
"word: woman" -> "word: women" [label="plural",arrowhead=normal]
}
And I guess that is about it for this post.

And a brief comment. We could tweak my script still further. So far I haven't made use of this notation:
"some node" -> {"a node" "b node" "c node"}
I've been using the long form:
"some node" -> "a node"
"some node" -> "b node"
"some node" -> "c node"

But I don't know if I can be bothered to do that. I'll think about it.
I guess it shouldn't be too hard. Just use " ".join(...).

Thursday, 3 December 2015

visualizing sw files

Happy to announce I made some major progress in the last couple of days! I discovered a nice tidy graph description language called DOT, and realized with not much work I could convert my sw files to DOT, and then use graphviz to plot the graphs. Suddenly, my math-looking sw files can now be made into pretty pictures (at least for smaller sw files. I tried names.sw but graphviz crashed out!).

This means I now have 4 ways to vizualize my sw data:
1) matrices
2) tables
3) bar charts
4) these network graphs

Now, let's give some examples.

Let's start with our earliest example, the www-document flow-chart.
For comparison, here is the sw:
|context> => |context: www proposal>

describes |document: www proposal> => |"Hypertext"> + |A Proposal "Mesh">
refers-to |document: www proposal> => |Comms ACM>
describes |Comms ACM> => |"Hypertext">
includes |"Hypertext"> => |Linked information> + |Hypermedia>
for-example |Linked information> => |Hyper Card> + |ENQUIRE> + |A Proposal "Mesh">
describes |a proposal "mesh"> => |CERN>
unifies |a proposal "mesh"> => |ENQUIRE> + |VAX/NOTES> + |uucp News> + |CERNDOC>
examples |Computer conferencing> => |IBM GroupTalk> + |uucp News> + |VAX/NOTES> + |A Proposal "Mesh">
for-example |Hierarchical systems> => |CERN> + |CERNDOC> + |Vax/Notes> + |uucp News> + |IBM GroupTalk>
includes |CERNDOC> => |document: www proposal>
wrote |person: Tim Berners-Lee> => |document: www proposal>
Here it is in DOT:
$ cat graph-examples/www-proposal.dot
digraph g {
context -> context_name
context_name [label="www proposal"]
n0 -> n1 [label="describes",arrowhead="normal"]
n0 -> n2 [label="describes",arrowhead="normal"]
n0 -> n3 [label="refers-to",arrowhead="normal"]
n3 -> n1 [label="describes",arrowhead="normal"]
n1 -> n4 [label="includes",arrowhead="normal"]
n1 -> n5 [label="includes",arrowhead="normal"]
n4 -> n6 [label="for-example",arrowhead="normal"]
n4 -> n7 [label="for-example",arrowhead="normal"]
n4 -> n2 [label="for-example",arrowhead="normal"]
n8 -> n9 [label="describes",arrowhead="normal"]
n8 -> n7 [label="unifies",arrowhead="normal"]
n8 -> n10 [label="unifies",arrowhead="normal"]
n8 -> n11 [label="unifies",arrowhead="normal"]
n8 -> n12 [label="unifies",arrowhead="normal"]
n13 -> n14 [label="examples",arrowhead="normal"]
n13 -> n11 [label="examples",arrowhead="normal"]
n13 -> n10 [label="examples",arrowhead="normal"]
n13 -> n2 [label="examples",arrowhead="normal"]
n15 -> n9 [label="for-example",arrowhead="normal"]
n15 -> n12 [label="for-example",arrowhead="normal"]
n15 -> n16 [label="for-example",arrowhead="normal"]
n15 -> n11 [label="for-example",arrowhead="normal"]
n15 -> n14 [label="for-example",arrowhead="normal"]
n12 -> n0 [label="includes",arrowhead="normal"]
n17 -> n0 [label="wrote",arrowhead="normal"]
n6 [label="Hyper Card"]
n1 [label="\"Hypertext\""]
n17 [label="person: Tim Berners-Lee"]
n10 [label="VAX/NOTES"]
n13 [label="Computer conferencing"]
n4 [label="Linked information"]
n7 [label="ENQUIRE"]
n2 [label="A Proposal \"Mesh\""]
n3 [label="Comms ACM"]
n5 [label="Hypermedia"]
n8 [label="a proposal \"mesh\""]
n14 [label="IBM GroupTalk"]
n16 [label="Vax/Notes"]
n9 [label="CERN"]
n11 [label="uucp News"]
n12 [label="CERNDOC"]
n15 [label="Hierarchical systems"]
n0 [label="document: www proposal"]
}
Here it is after graphviz does its thing:
Here is another example. First the sw:
|context> => |context: friends>

friends |Fred> => |Jack> + |Harry> + |Ed> + |Mary> + |Rob> + |Patrick> + |Emma> + |Charlie>
friends |Sam> => |Charlie> + |George> + |Emma> + |Jack> + |Rober> + |Frank> + |Julie>
Here is the DOT:
digraph g {
context -> context_name
context_name [label="friends"]
n0 -> n1 [label="friends",arrowhead="normal"]
n0 -> n2 [label="friends",arrowhead="normal"]
n0 -> n3 [label="friends",arrowhead="normal"]
n0 -> n4 [label="friends",arrowhead="normal"]
n0 -> n5 [label="friends",arrowhead="normal"]
n0 -> n6 [label="friends",arrowhead="normal"]
n0 -> n7 [label="friends",arrowhead="normal"]
n0 -> n8 [label="friends",arrowhead="normal"]
n9 -> n8 [label="friends",arrowhead="normal"]
n9 -> n10 [label="friends",arrowhead="normal"]
n9 -> n7 [label="friends",arrowhead="normal"]
n9 -> n1 [label="friends",arrowhead="normal"]
n9 -> n11 [label="friends",arrowhead="normal"]
n9 -> n12 [label="friends",arrowhead="normal"]
n9 -> n13 [label="friends",arrowhead="normal"]
n6 [label="Patrick"]
n9 [label="Sam"]
n8 [label="Charlie"]
n7 [label="Emma"]
n11 [label="Rober"]
n13 [label="Julie"]
n10 [label="George"]
n0 [label="Fred"]
n5 [label="Rob"]
n2 [label="Harry"]
n1 [label="Jack"]
n4 [label="Mary"]
n12 [label="Frank"]
n3 [label="Ed"]
}
And after graphviz does its thing:
Here is methanol.sw:
|context> => |context: methanol>

molecular-pieces |molecule: methanol> => |methanol: 1> + |methanol: 2> + |methanol: 3> + |methanol: 4> + |methanol: 5> + |methanol: 6>

atom-type |methanol: 1> => |atom: H>
bonds-to |methanol: 1> => |methanol: 4>

atom-type |methanol: 2> => |atom: H>
bonds-to |methanol: 2> => |methanol: 4>

atom-type |methanol: 3> => |atom: H>
bonds-to |methanol: 3> => |methanol: 4>

atom-type |methanol: 4> => |atom: C>
bonds-to |methanol: 4> => |methanol: 1> + |methanol: 2> + |methanol: 3> + |methanol: 5>

atom-type |methanol: 5> => |atom: O>
bonds-to |methanol: 5> => |methanol: 4> + |methanol: 6>

atom-type |methanol: 6> => |atom: H>
bonds-to |methanol: 6> => |methanol: 5>
Here is methanol.dot:
digraph g {
context -> context_name
context_name [label="methanol"]
n0 -> n1 [label="molecular-pieces",arrowhead="normal"]
n0 -> n2 [label="molecular-pieces",arrowhead="normal"]
n0 -> n3 [label="molecular-pieces",arrowhead="normal"]
n0 -> n4 [label="molecular-pieces",arrowhead="normal"]
n0 -> n5 [label="molecular-pieces",arrowhead="normal"]
n0 -> n6 [label="molecular-pieces",arrowhead="normal"]
n1 -> n7 [label="atom-type",arrowhead="normal"]
n1 -> n4 [label="bonds-to",arrowhead="normal"]
n2 -> n7 [label="atom-type",arrowhead="normal"]
n2 -> n4 [label="bonds-to",arrowhead="normal"]
n3 -> n7 [label="atom-type",arrowhead="normal"]
n3 -> n4 [label="bonds-to",arrowhead="normal"]
n4 -> n8 [label="atom-type",arrowhead="normal"]
n4 -> n1 [label="bonds-to",arrowhead="normal"]
n4 -> n2 [label="bonds-to",arrowhead="normal"]
n4 -> n3 [label="bonds-to",arrowhead="normal"]
n4 -> n5 [label="bonds-to",arrowhead="normal"]
n5 -> n9 [label="atom-type",arrowhead="normal"]
n5 -> n4 [label="bonds-to",arrowhead="normal"]
n5 -> n6 [label="bonds-to",arrowhead="normal"]
n6 -> n7 [label="atom-type",arrowhead="normal"]
n6 -> n5 [label="bonds-to",arrowhead="normal"]
n6 [label="methanol: 6"]
n0 [label="molecule: methanol"]
n2 [label="methanol: 2"]
n4 [label="methanol: 4"]
n3 [label="methanol: 3"]
n9 [label="atom: O"]
n5 [label="methanol: 5"]
n8 [label="atom: C"]
n1 [label="methanol: 1"]
n7 [label="atom: H"]
}
Here is methanol.png:
Here is the adjacency matrix from the movie "Good Will Hunting":
|context> => |context: good will hunting adjacency matrix>

adj |1> => |2> + |4>
adj |2> => |1> + |4> + 2|3>
adj |3> => 2|2>
adj |4> => |1> + |2>
Here is good-will-hunting-adjacency-matrix.dot:
digraph g {
context -> context_name
context_name [label="good will hunting adjacency matrix"]
n0 -> n1 [label="adj",arrowhead="normal"]
n0 -> n2 [label="adj",arrowhead="normal"]
n1 -> n0 [label="adj",arrowhead="normal"]
n1 -> n2 [label="adj",arrowhead="normal"]
n1 -> n3 [label="adj",arrowhead="normal"]
n3 -> n1 [label="adj",arrowhead="normal"]
n2 -> n0 [label="adj",arrowhead="normal"]
n2 -> n1 [label="adj",arrowhead="normal"]
n3 [label="3"]
n0 [label="1"]
n2 [label="4"]
n1 [label="2"]
}
Here is the graph:
Here is a simple network:
O |a1> => |a2>
O |a2> => |a3>
O |a3> => |a4>
O |a4> => |a5>
O |a5> => |a6>
O |a6> => |a7>
O |a7> => |a8>
O |a8> => |a9>
O |a9> => |a10>
O |a10> => |a1> + |b1>

O |b1> => |b2>
O |b2> => |b3>
O |b3> => |b4>
O |b4> => |b5>
O |b5> => |b6>
O |b6> => |b7>
O |b7> => |b1>
Here is the DOT:
digraph g {
n0 -> n1 [label="O",arrowhead="normal"]
n1 -> n2 [label="O",arrowhead="normal"]
n2 -> n3 [label="O",arrowhead="normal"]
n3 -> n4 [label="O",arrowhead="normal"]
n4 -> n5 [label="O",arrowhead="normal"]
n5 -> n6 [label="O",arrowhead="normal"]
n6 -> n7 [label="O",arrowhead="normal"]
n7 -> n8 [label="O",arrowhead="normal"]
n8 -> n9 [label="O",arrowhead="normal"]
n9 -> n0 [label="O",arrowhead="normal"]
n9 -> n10 [label="O",arrowhead="normal"]
n10 -> n11 [label="O",arrowhead="normal"]
n11 -> n12 [label="O",arrowhead="normal"]
n12 -> n13 [label="O",arrowhead="normal"]
n13 -> n14 [label="O",arrowhead="normal"]
n14 -> n15 [label="O",arrowhead="normal"]
n15 -> n16 [label="O",arrowhead="normal"]
n16 -> n10 [label="O",arrowhead="normal"]
n16 [label="b7"]
n3 [label="a4"]
n6 [label="a7"]
n0 [label="a1"]
n13 [label="b4"]
n15 [label="b6"]
n4 [label="a5"]
n11 [label="b2"]
n9 [label="a10"]
n7 [label="a8"]
n5 [label="a6"]
n12 [label="b3"]
n2 [label="a3"]
n10 [label="b1"]
n14 [label="b5"]
n1 [label="a2"]
n8 [label="a9"]
}
Here is the image:
And finally, let's finish with the early US presidents. sw-file, dot-file, and the image:
Anyway, all nice and pretty!
Some more dot files and png files.