inverse

So, one driving idea of the project is to get the computer to do as much learning by itself that it can. If we can automate some learning task, then we should try to do so.

The other idea behind "inverse" is that it seems biologically plausible.
Say a face.
A face links one way to the name of that face.
But it links the other way too. The name of the face (usually) invokes the mental image of that face.
Another example is the child/parent relation.
A child relation maps a mother to her children.
But the inverse-child relation maps a child to the mother.
So maybe we can do that a little here?

Again, a simple example:
-- learn a simple rule:
sa: op |x> => |a> + |b> + |c>

-- create the set of inverses:
sa: create inverse
sa: dump
----------------------------------------
|context> => |context: sw console>

op |x> => |a> + |b> + |c>

inverse-supported-ops |op: op> => |x>

inverse-op |a> => |x>

inverse-op |b> => |x>

inverse-op |c> => |x>

inverse-supported-ops |op: inverse-supported-ops> => |op: op> + |op: inverse-supported-ops> + |op: inverse-op>

inverse-supported-ops |op: inverse-op> => |a> + |b> + |c>
----------------------------------------
Hrmm... that is kind of a mess. Unfortunately, the output after "create inverse" usually is.
But let's try and explain what's going on.
Say we have:
OP KET-1 => SUPERPOSITION
then when we run "create inverse" for all rules (in the current context) we learn:
inverse-OP ket => KET-1
for all ket's in SUPERPOSITION.

Maybe this example will be clearer:
-- learn the children of Mary and James:
sa: child |Mary> => |Tim> + |Liz> + |Jane> + |Rob>
sa: child |James> => |Tim> + |Liz> + |Jane> + |Rob>

sa: create inverse
sa: dump
----------------------------------------
|context> => |context: sw console>

child |Mary> => |Tim> + |Liz> + |Jane> + |Rob>

child |James> => |Tim> + |Liz> + |Jane> + |Rob>

inverse-supported-ops |op: child> => |Mary> + |James>

inverse-child |Tim> => |Mary> + |James>

inverse-child |Liz> => |Mary> + |James>

inverse-child |Jane> => |Mary> + |James>

inverse-child |Rob> => |Mary> + |James>

inverse-supported-ops |op: inverse-supported-ops> => |op: child> + |op: inverse-supported-ops> + |op: inverse-child>

inverse-supported-ops |op: inverse-child> => |Tim> + |Liz> + |Jane> + |Rob>
----------------------------------------
So given just data on who Mary and Jame's children are, it auto-learnt the inverse relation. eg, Tim's parents (ie inverse-child) are Mary and James.

Here is another example, in a different region of knowledge, primes.
Start with this data:
-- load data from file:
sa: load short-list-primes.sw
sa: dump
----------------------------------------
|context> => |context: sw console>

is-prime |2> => |yes>
is-prime |3> => |yes>
is-prime |4> => |no>
is-prime |5> => |yes>
is-prime |6> => |no>
is-prime |7> => |yes>
is-prime |8> => |no>
is-prime |9> => |no>
is-prime |10> => |no>
is-prime |11> => |yes>
is-prime |12> => |no>
is-prime |13> => |yes>
is-prime |14> => |no>
is-prime |15> => |no>
is-prime |16> => |no>
is-prime |17> => |yes>
is-prime |18> => |no>
is-prime |19> => |yes>
is-prime |20> => |no>
----------------------------------------

Now, create inverses:
sa: create inverse
sa: dump
----------------------------------------
|context> => |context: sw console>

is-prime |2> => |yes>
is-prime |3> => |yes>
is-prime |4> => |no>
is-prime |5> => |yes>
is-prime |6> => |no>
is-prime |7> => |yes>
is-prime |8> => |no>
is-prime |9> => |no>
is-prime |10> => |no>
is-prime |11> => |yes>
is-prime |12> => |no>
is-prime |13> => |yes>
is-prime |14> => |no>
is-prime |15> => |no>
is-prime |16> => |no>
is-prime |17> => |yes>
is-prime |18> => |no>
is-prime |19> => |yes>
is-prime |20> => |no>

inverse-supported-ops |op: is-prime> => |2> + |3> + |4> + |5> + |6> + |7> + |8> + |9> + |10> + |11> + |12> + |13> + |14> + |15> + |16> + |17> + |18> + |19> + |20>

inverse-is-prime |yes> => |2> + |3> + |5> + |7> + |11> + |13> + |17> + |19>

inverse-is-prime |no> => |4> + |6> + |8> + |9> + |10> + |12> + |14> + |15> + |16> + |18> + |20>

inverse-supported-ops |op: inverse-supported-ops> => |op: is-prime> + |op: inverse-supported-ops> + |op: inverse-is-prime>

inverse-supported-ops |op: inverse-is-prime> => |yes> + |no>
----------------------------------------
(note, some new-lines chomped from the dump for readability)

Anyway, the coolness is in these two lines:
inverse-is-prime |yes> => |2> + |3> + |5> + |7> + |11> + |13> + |17> + |19>
inverse-is-prime |no> => |4> + |6> + |8> + |9> + |10> + |12> + |14> + |15> + |16> + |18> + |20>

So, given just yes/no on primes for each number, the create inverse automatically spits out a list of primes, and non-primes. I personally think that is quite cool!

Technical note: it would be nice if "create inverse" was idempotent, but every now and then it is not.

More to come!


Home
previous: supported ops and apply
next: train of thought

updated: 19/12/2016
by Garry Morrison
email: garry -at- semantic-db.org