PLN Rules/Formulas and the Pattern Matcher

74 views
Skip to first unread message

Ben Goertzel

unread,
Apr 26, 2013, 2:26:14 AM4/26/13
to linasv...@gmail.com, opencog, hk-a...@opencog.org
Hi Linas,

So... Ramin is tasked with getting the new PLN implementation started
ASAP.... He is an OpenCog newbie, but he's a good programmer and has
full time to devote to this for a while....

I want to be sure the new PLN implementation starts off on the right
foot.... So your detailed constructive feedback at this precise
juncture will be quite critical, I think...

You mention some prior emails in your reply -- but there have been
lots of emails and I can't quickly find the ones you're referring
to...

This is a long and slightly technical email but I hope you can take
the time to read and respond carefully, thanks ;) .... Also, if it's
not too much of an imposition, I suggest you read the whole email
before replying to the initial portions....

In short: to make things simple and avoid confusion, it would be great
if you could take a little time and give us an example of EXACTLY how
to formulate the PLN deduction rule (as a first example rule) using
the pattern matcher...

1)
DEDUCTION RULE SPECIFICATION

Let us assume a simple form of the deduction rule, conceptually specified as

******
INPUT:
A pair of links, (Inheritance A B), (Inheritance B C)

OUTPUT:
A link (Inheritance A C) with appropriate truth value

TRUTH VALUE FORMULA:
For now let's just worth about the strength component of the truth
value, given in Latex notation at

s_{AC}=s_{AB}s_{BC}+\frac{\left(1-s_{AB}\right)\left(s_C-s_Bs_{BC}\right)}{1-s_B}

Just assume the confidence of the conclusion is the max of the
confidences of the premises, i.e.

c_{AC} = max( c_A{AB}, c_{AC} )
*****

2)
SKETCH OF A SIMPLE DEDUCTION RULE IMPLEMENTATION

Now I will describe, using rough pseudocode, how one could implement
this rule in OpenCog

(And then afterward, hopefully you can tell me what is the better way
to do it using the pattern matcher... though I will share some
inklings about that as well...)

The simple way to do it, would be to write a C++ function of the form
(pseudocode below)

***
Atom deductionRule(Atom AB, Atom BC)
{
check to be sure AB and BC are InheritanceLinks of the form
(Inheritance A B), (Inheritance B C)

produce the conclusion Atom, and invoke the deductionFormula()
function to get its truth value
}

SimpleTV deductionFormula(SimpleTV tvAB, SimpleTV tvBC, SimpleTV tvA,
SimpleTV tvB, SimpleTV tvC)
{
produce the truth value of (Inheritance A C) according to the formulas
given above in this email
}

***


One could then write a simple forward chaining function like

***

Atom forwardInferenceStep(Atom X) {

If X is of the form (Inheritance AB), then (and I'll ignore other
cases for now) {

Use the pattern matcher to find an Atom Y of the form

Inheritance B C

or

Inheritance C B

Then, apply DeductionRule(X, Y)

}

}
****

A forward chaining MindAgent would then choose Atoms according to some
function (e.g. Atoms with high STI), and invoke the
forwardInferenceStep function on each one...

3)
DOING THE ABOVE USING THE PATTERN MATCHER

So, Linas, on to the next step...

According to my understanding of what you're saying, your main message
is that the guts of a function like DeductionRule() above could be
replaced by an ImplicationLink intended for use by the pattern
matcher... is that right?

So instead of a C++ function DeductionRule(), you would write (in Scheme syntax)

BindLink $A, $B, $C
ImplicationLink
ANDLink
Inheritance $A $B
Inheritance $B $C
Inheritance $A $C


and then write explicit code somewhere to invoke the deductionFormula
for determining the truth value sAC of the conclusion...

Is that right?

That is OK, but in terms of the functions I defined above, it does not
obviate either deductionFormula or forwardInferenceStep.... It
replaces only deductionRule ...

Am I understanding you correctly? If not, please clarify...

ADDITIONAL COMMENT:

One thing that I want to clarify: We don't really need a function of the form

"Find an arbitrary Atom pair of the form (X, Y), where X = Inheritance
A B, and Y = Inheritance B C, and then apply the deduction rule to the
premises X and Y."

I suspect a function of the above form could be trivially written
using the pattern matcher, but it's not what we need...

We could use a function of the form

"Find a pair of the form (X, Y), where X = Inheritance A B, and Y =
Inheritance B C, and X and Y both are chosen randomly from the Atoms
with STI higher than the AttentionalFocusBoundary; then apply the
deduction rule to the premises X and Y."

however, I'm unclear if the pattern matcher does stuff like that....
If it does, explaining exactly how to use it in such a way would be
valuable...



4)
A HUMBLE REQUEST

Linas, I know you're busy with other stuff. But my suggestion, if
you can find the time, is for you to actually implement the PLN
deduction rule using the pattern matcher, in a way that concords with
the suggestions you've been making...

Given your simple implementation of the PLN deduction rule using the
pattern matcher, assuming the approach makes sense to the rest of us
after we understand all the details, it should be straightforward for
us to implement the other PLN rules in a similar way...

Otherwise, if you don't have time to implement the rule, the more
detailed guidance you can provide the better...

thanks
Ben






On Fri, Apr 26, 2013 at 4:46 AM, Linas Vepstas <linasv...@gmail.com> wrote:
> Hi,
>
> Most of this seems reasonable (I just skimmed it), until I get to the very
> last section "Programming Language Issues" which leaves me with a big
> spinning, blinking WTF? in my mind.
>
> Why are there programming language issues at all? This part has already been
> coded, tested, documented, and it works. Its called the pattern matcher.
> There is very little code to be written: you just have to write your rules
> and formulas as hypergraphs, and you're done. The emails from a week or two
> ago even provided examples on how to do this, how these would work. Open a
> shell to the cog-server. Cut-n-paste from the email to the command line. The
> examples actually work, and give you the correct truth values, and forward
> chain and all the rest. You can trivially change them to increment or
> decrement the attention values too. This is easy, and takes maybe 1-2 lines
> of code total.
>
> --linas
>
>
>
> On 24 April 2013 03:52, Ben Goertzel <b...@goertzel.org> wrote:
>>
>> I have updated the wiki page on the proposed new PLN design, to
>> contain some much more detailed examples and discussion on the
>> "trickiest parts" [how to do backward chaining in this framework, and
>> also how to achieve the effect of backward chaining without actually
>> doing backward chaining...]
>>
>> http://wiki.opencog.org/w/New_PLN_Design,_2013
>>
>> thx
>> ben
>>
>> --
>> Ben Goertzel, PhD
>> http://goertzel.org
>>
>> "My humanity is a constant self-overcoming" -- Friedrich Nietzsche
>
>



--
Ben Goertzel, PhD
http://goertzel.org

"My humanity is a constant self-overcoming" -- Friedrich Nietzsche

Linas Vepstas

unread,
Apr 26, 2013, 12:23:57 PM4/26/13
to Ben Goertzel, opencog, hk-a...@opencog.org
Hi,

As a baseline, I'd like everyone to read through 


You can skim the middle part about variables (it gets complicated) but do study the examples in the sections called "evaluation" and "execution".

On 26 April 2013 01:26, Ben Goertzel <b...@goertzel.org> wrote:

In short: to make things simple and avoid confusion, it would be great
if you could take a little time and give us an example of EXACTLY how
to formulate the PLN deduction rule (as a first example rule) using
the pattern matcher...

1)
DEDUCTION RULE SPECIFICATION

Let us assume a simple form of the deduction rule, conceptually specified as

******
INPUT:
A pair of links, (Inheritance A B), (Inheritance B C)

OUTPUT:
A link (Inheritance A C) with appropriate truth value

TRUTH VALUE FORMULA:
For now let's just worth about the strength component of the truth
value, given in Latex notation at

s_{AC}=s_{AB}s_{BC}+\frac{\left(1-s_{AB}\right)\left(s_C-s_Bs_{BC}\right)}{1-s_B}

Just assume the confidence of the conclusion is the max of the
confidences of the premises, i.e.

c_{AC} = max( c_A{AB}, c_{AC} )
*****

If you already *know* (have somehow found) the inputs, then you certainly do not need the pattern matcher.  You can write the above in C++ or python or scheme.  I don't care.  

I'm confused by the terminology, though. I thought the above was called "a formula" and not "a rule".   That is, *if you already know what the atoms are*, then, I thought that setting the truth value(s) on some other output atom(s) is called a "formula", not a "rule".  So if the above is a "rule", then what is "a formula" ??

The "Execution" section  of the wiki page has two examples of such things, (which are called "formulas", there).  The first starts with


(define (my-formula h)
The second with

(define (my-formula ha hb)

The second is in the style that you would want (since it takes two inputs). The 'formula' (rule) in that example simply sets the truth value on the second atom to be 0.3 times the truth value of the first atom.

I don't want to give a tutorial (at this time) about how to program in scheme.  The above would not be hard, but would be beside the point.   The above could be written in python, scheme or C++, and I don't really care.  I think that python or scheme would be much easier than C++, but C++ would be faster.

However, lets continue.  In that wiki page, in the execution section, we see this snippet:

        ;; This will be executed if the above pattern is found.
(ExecutionLink (GroundedSchemaNode "scm: my-formula")

If you want to use the pattern matcher to execute the above formula/rule, whenever the correct inputs are found, then you need to use an ExecutionLink and GroundedSchemaNode, just like the above.  The "scm: my-formula" says that the formula/rule is implemented in scheme, and what its function name is.

You could write this as:

        ;; This will be executed if the above pattern is found.
(ExecutionLink (GroundedSchemaNode "http://my-formula.com/some.java")
I don't care.  However, there currently is no handler for http:// so that would not work.  I started writing a handler for python  (so that these formulas/rules could be written in python) but I could not get it to work.  See /opencog/query/PatternMatch.cc line 225 -- if you can fix that, then you can use python to write rules/formulas.

In order to write rules/formulas in C++, you would have to invent some sort of URL handler, like "C++:/MyClass::MyStaticMethod" or something like that, and some way of automatically guessing how many arguments there are, and then thunking them correctly, as needed.  It could be ugly; C++ was not designed to be used this way.  But with enough hacking, its ugly but doable.

(For example, you could write a scheme wrapper for the C++ code, and then use the "scm:my-formula-wrapper" URL to invoke the wrapper.  That might be the easiest solution.  Not the fastest, but the simplest.)


2)
SKETCH OF A SIMPLE DEDUCTION RULE IMPLEMENTATION

Now I will describe, using rough pseudocode, how one could implement
this rule in OpenCog

(And then afterward, hopefully you can tell me what is the better way
to do it using the pattern matcher... though I will share some
inklings about that as well...)

The simple way to do it, would be to write a C++ function of the form
(pseudocode below)

***
Atom deductionRule(Atom AB, Atom BC)
{
check to be sure AB and BC are InheritanceLinks of the form
(Inheritance A B), (Inheritance B C)

produce the conclusion Atom, and invoke the deductionFormula()
function to get its truth value
}

Again, I thought the above was called a "formula" and not a "rule".   Again, if you already know what your arguments are, you would not use the pattern matcher.

Again, you can write the above in C++ or python or scheme, I don't care -- except that currently, GroundedSchemaNode can only be used with scheme, until PatternMatch.cc line 225  is extended/enhanced.


SimpleTV deductionFormula(SimpleTV tvAB, SimpleTV tvBC, SimpleTV tvA,
SimpleTV tvB, SimpleTV tvC)
{
produce the truth value of (Inheritance A C) according to the formulas
given above in this email
}


Oh, is that what a formula is?  OK.   If this is the naming convention for formulas and rules, then what is the third thing called?  The actual thing that is being done?  In my mind (and earlier emails), I've been calling it a "rule", but clearly this contradicts the definition of "rule" above.  


Hmm. Below, I see that what I was calling a "rule" you call an "inference step".  This seems rather awkward to me ... because usually, in comp-sci books,  the thing that you are calling "forwardInferenceStep" is called a "production rule".  I think this is the source of some confusion.

 
***


One could then write a simple forward chaining function like

***

Atom forwardInferenceStep(Atom X) {

If X is of the form (Inheritance AB), then (and I'll ignore other
cases for now) {

Use the pattern matcher to find an Atom Y of the form

Inheritance B C

or

Inheritance C B

Then, apply DeductionRule(X, Y)


}
****

Yes, the above would be done with the pattern matcher.
 
A forward chaining MindAgent would then choose Atoms according to some
function (e.g. Atoms with high STI), and invoke the
forwardInferenceStep function on each one...

No, that's completely wrong. If your mind agent already knows about and is able to choose the right atoms, then there is no need for a pattern matcher.  The pattern matcher exists solely for classical, text-book style application of production rules, where you have a set of production rules (graph re-write rules, in this case), and you want to apply them. 

Think of relex. The pattern matcher does exactly what relex does, except it does it for hypergraphs instead of ordinary labelled graphs.   

I really dislike that you called the above a "ForwardInferenceStep".  Everyone else calls this a "rule".  So for example: in http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form its called a "derivation rule" and not an "inference step"

Similarly https://en.wikipedia.org/wiki/Rewrite_rule  ... "rule" is in the title. Its not called ForwardInferenceStep.  I think its a mistake to use a different terminology than what everyone else uses...  I would really really like it if we used standard textbook terminology for these things.


3)
DOING THE ABOVE USING THE PATTERN MATCHER

So, Linas, on to the next step...

According to my understanding of what you're saying, your main message
is that the guts of a function like DeductionRule() above could be
replaced by an ImplicationLink intended for use by the pattern
matcher... is that right?

No... this is where the confusion starts. To me, what you are calling DeductionRule is not actually rule, its something else entirely.   

The pattern matcher is designed to accept rules, as defined in https://en.wikipedia.org/wiki/Rewrite_rule  and apply those.  You could say that the pattern matcher is a rewrite-rule-engine, or a production-rule-applier, using textbook definitions of "production rule".

One thing that I want to clarify: We don't really need a function of the form

"Find an arbitrary Atom pair of the form (X, Y), where X = Inheritance
A B, and Y = Inheritance B C, and then apply the deduction rule to the
premises X and Y."

well, the pattern matcher actually finds *all* such atoms, not just "arbitrary ones".
 
I suspect a function of the above form could be trivially written
using the pattern matcher, but it's not what we need...

OK, maybe you don't need the pattern matcher, but ... I don't understand.   You keep  talking about forward and backward chaining, and I keep saying that the pattern matcher is a forward chainer, and then you write "but it's not what we need..."  

This leaves me thoroughly confused.  Do you need a forward chainer, or not?  Because if you do, I've got one... 



We could use a function of the form

"Find a pair of the form (X, Y), where X = Inheritance A B, and Y =
Inheritance B C, and X and Y both are chosen randomly from the Atoms
with STI higher than the AttentionalFocusBoundary; then apply the
deduction rule to the premises X and Y."

however, I'm unclear if the pattern matcher does stuff like that....

Of course it does stuff like that. That is more or less the only thing it does. It is it's one and central raison d'etre.  But three sentences ago, you just said that you don't need this.  !?!?  Do you, or do you not need this?  You are confusing me.
 
If it does, explaining exactly how to use it in such a way would be
valuable...

...!?  Please read the wiki page http://wiki.opencog.org/w/BindLink This wiki page explains, in considerable detail, how to write a graph re-write rule that will

"Find a pair of the form (X, Y), where X = Inheritance A B, and Y =
Inheritance B C, and X and Y both are chosen randomly from the Atoms
with STI higher than the AttentionalFocusBoundary; then apply the
deduction rule to the premises X and Y."

4)
A HUMBLE REQUEST

My humble request: please read the wiki page, and try to understand what it's saying.  The examples there actually run.  You can modify them to add "STI higher than AttentionalFocusBoundary", this is not at all hard. It would be a good beginner's  exercise. It should not take more than an afternoon.  Maybe two or three if you don't know lisp/scheme.

The only issue is that, what you call "rules", that wiki page calls "formulas", and what you call "inference steps", that wiki page calls "rules".  If you can keep this in mind, then its smooth sailing. Otherwise .. I dunno.

-- Linas

Ben Goertzel

unread,
Apr 27, 2013, 2:34:56 AM4/27/13
to linasv...@gmail.com, Ramin Barati, opencog, hk-a...@opencog.org
Hi Linas,

Thanks a lot for the detailed reply...

> As a baseline, I'd like everyone to read through
>
> http://wiki.opencog.org/w/BindLink
>
> You can skim the middle part about variables (it gets complicated) but do
> study the examples in the sections called "evaluation" and "execution".

I have just re-read that and

http://wiki.opencog.org/w/Pattern_matcher

as well ... there was nothing new to me there.... (Though I had forgotten
how thorough the examples there were....) But for Ramin, Amen
and other newbies that is a helpful pointer, thx ;)

>> 1)
>> DEDUCTION RULE SPECIFICATION
>>
>> Let us assume a simple form of the deduction rule, conceptually specified
>> as
...
> If you already *know* (have somehow found) the inputs, then you certainly do
> not need the pattern matcher.

Yes, as I thought.... Of course, the inputs must be found at some point;
I'll get to that below...

> I'm confused by the terminology, though. I thought the above was called "a
> formula" and not "a rule". That is, *if you already know what the atoms
> are*, then, I thought that setting the truth value(s) on some other output
> atom(s) is called a "formula", not a "rule". So if the above is a "rule",
> then what is "a formula" ??

In the terminology used in PLN,

Inheritance A B
Inheritance B C
|-
Inheritance A C

is the Deduction Rule, whereas

s_{AC}=s_{AB}s_{BC}+\frac{\left(1-s_{AB}\right)\left(s_C-s_Bs_{BC}\right)}{1-s_B}

is the standard Deduction (truth value strength) Formula

This terminology was borrowed from Pei Wang's NARS system, and has been used
in many publications -- and also in the C++ and and python versions of
PLN. So it
wouldn't make sense to change it now, even if it's suboptimal...

The forward and backward inference steps I have defined, are atomic steps that
*choose* a rule to apply, and (usually) an Atom to use together with the rule...

Sorry if my email and wiki page were somehow unclear...

> The "Execution" section of the wiki page has two examples of such things,
> (which are called "formulas", there). The first starts with
>
>
> (define (my-formula h)
>
> The second with
>
> (define (my-formula ha hb)
>
>
> The second is in the style that you would want (since it takes two inputs).
> The 'formula' (rule) in that example simply sets the truth value on the
> second atom to be 0.3 times the truth value of the first atom.

Yeah, thanks for pointing out that example to me; I had forgotten it was
there...

Indeed, that is a good example for how to write a PLN Inference Rule
in Scheme....

And as you point out, it would go about the same in python or C++

> However, lets continue. In that wiki page, in the execution section, we see
> this snippet:
>
> ;; This will be executed if the above pattern is found.
> (ExecutionLink
> (GroundedSchemaNode "scm: my-formula")
>
>
> If you want to use the pattern matcher to execute the above formula/rule,
> whenever the correct inputs are found, then you need to use an ExecutionLink
> and GroundedSchemaNode, just like the above. The "scm: my-formula" says
> that the formula/rule is implemented in scheme, and what its function name
> is.

Understood...

> You could write this as:
>
> ;; This will be executed if the above pattern is found.
> (ExecutionLink
> (GroundedSchemaNode "http://my-formula.com/some.java")
>
> I don't care. However, there currently is no handler for http:// so that
> would not work. I started writing a handler for python (so that these
> formulas/rules could be written in python) but I could not get it to work.
> See /opencog/query/PatternMatch.cc line 225 -- if you can fix that, then you
> can use python to write rules/formulas.

Hmmm.... It would be good for someone to fix, that, indeed...

> In order to write rules/formulas in C++, you would have to invent some sort
> of URL handler, like "C++:/MyClass::MyStaticMethod" or something like that,
> and some way of automatically guessing how many arguments there are, and
> then thunking them correctly, as needed. It could be ugly; C++ was not
> designed to be used this way. But with enough hacking, its ugly but doable.
>
> (For example, you could write a scheme wrapper for the C++ code, and then
> use the "scm:my-formula-wrapper" URL to invoke the wrapper. That might be
> the easiest solution. Not the fastest, but the simplest.)

Thanks for the details...

I think that implementing PLN rules/formulas in C++ is not important... these
are (obviously) simple, non-processor-intensive pieces of code, that
don't require the
power of C++...

> Again, you can write the above in C++ or python or scheme, I don't care --
> except that currently, GroundedSchemaNode can only be used with scheme,
> until PatternMatch.cc line 225 is extended/enhanced.

Thanks, that is an important piece of information...

I think I will leave that up to Ramin -- whether he would rather code the PLN
rules/formulas in Scheme, or fix Patternmatch.cc

Either approach seems generally acceptable to me...

> Hmm. Below, I see that what I was calling a "rule" you call an "inference
> step". This seems rather awkward to me ... because usually, in comp-sci
> books, the thing that you are calling "forwardInferenceStep" is called a
> "production rule". I think this is the source of some confusion.

Well, in logic, things like

A
A -->B
|-
B

are generally called rules (e.g. Modus Ponens rule, etc.). So I don't think
my terminology here is strange.... Rather, I suppose my writing was
somehow unclear, so that you misunderstood me...

>> One could then write a simple forward chaining function like
>>
>> ***
>>
>> Atom forwardInferenceStep(Atom X) {
>>
>> If X is of the form (Inheritance AB), then (and I'll ignore other
>> cases for now) {
>>
>> Use the pattern matcher to find an Atom Y of the form
>>
>> Inheritance B C
>>
>> or
>>
>> Inheritance C B
>>
>> Then, apply DeductionRule(X, Y)
...
> Yes, the above would be done with the pattern matcher.


OK, glad I understood that right...


>> A forward chaining MindAgent would then choose Atoms according to some
>> function (e.g. Atoms with high STI), and invoke the
>> forwardInferenceStep function on each one...
>
>
> No, that's completely wrong. If your mind agent already knows about and is
> able to choose the right atoms, then there is no need for a pattern matcher.
> The pattern matcher exists solely for classical, text-book style application
> of production rules, where you have a set of production rules (graph
> re-write rules, in this case), and you want to apply them.

Hmmm... actually I think you are completely wrong in your assertion that I was
completely wrong ;-) .... But, we shall see !! ...

It seems to me that a forward chaining MindAgent, designed as I've suggested,
could use the pattern matcher **within each inference step** perfectly well...
even though it is controlling its overall activities differently from
a textbook-style production
system...

For example, suppose that a forward chaining MindAgent has

-- chosen the Atom (Inheritance cat animal)

-- chosen the DeductionRule to guide its next inference step

Then this MindAgent would use the pattern matcher to launch a query

****
(define find-cats
(BindLink
;; The variable to be bound
(VariableNode "$var")
(InheritanceLink
;; The pattern to be searched for
(InheritanceLink
(VariableNode "$var")
(ConceptNode "cat")
)

;; The value to be returned.
(VariableNode "$var")
)
)
)

;; Run the above pattern
(cog-bind find-cats)
****

and would then also launch a comparable query

****
(define find-what-animals-are
(BindLink
;; The variable to be bound
(VariableNode "$var")
(InheritanceLink
;; The pattern to be searched for
(InheritanceLink
(ConceptNodeNode "animal")
(ConceptNode "$var")
)

;; The value to be returned.
(VariableNode "$var")
)
)
)

;; Run the above pattern
(cog-bind find-what-animals-are)
****

The pattern matcher would then respond to the find-cats query with stuff like


(InheritanceLink (ConceptNode "Fluffy") (ConceptNode "cat"))
(InheritanceLink (ConceptNode "Jerry") (ConceptNode "cat"))

and would respond to the find-what-animals-are query with stuff like

(InheritanceLink (ConceptNode "animal") (ConceptNode "alive"))
(InheritanceLink (ConceptNode "animal") (ConceptNode "mobile"))

Then the forward chaining MindAgent would look at the truth values of
these links,
and [for example] choose one of them via roulette selection, where the
probability
of choosing one of them is proportional to [say]

truthvalue.strength * truthvalue.confidence * normalized_STI

(where normalized_STI is the ShortTermImportance of an Atom, normalized into
[0.1]). So the forward chainer will have a preference, among the
multiple links
returned by the pattern matcher, for InheritanceLinks that are both
confidently true, and important...

Let's say the forward chaining agent chose

(InheritanceLink (ConceptNode "animal") (ConceptNode "alive"))

via this process.... Then it would invoke the PLN deduction rule to infer

Inheritance cat animal
Inheritance animal alive
|-
Inheritance cat alive

and it would create an Atom

(InheritanceLink (ConceptNode "cat") (ConceptNode "alive"))

and assign this Atom a truth value determined by the PLN deduction formula
(which was invoked by the PLN deduction rule) .... It would also give some
STI to this new Atom....

Then, next cycle, the forward chainer would pluck another Atom out of the
AttentionalFocus (the set of Atoms with STI > AttentionalFocusBoundary),
and try the same thing over again. It might pick the newly created Atom
(Inheritance cat alive), or maybe something else in the AttentionalFocus...

...

So, as you see, it seems quite feasible to use the pattern matcher within
a customized PLN control strategy....

Do you see something wrong with the above? If so please do tell me, because
that is basically how I'm thinking Ramin should implement the initial forward
inference step code...


> I really dislike that you called the above a "ForwardInferenceStep".
> Everyone else calls this a "rule". So for example: in
> http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form its called a
> "derivation rule" and not an "inference step"
>
> Similarly https://en.wikipedia.org/wiki/Rewrite_rule ... "rule" is in the
> title. Its not called ForwardInferenceStep. I think its a mistake to use a
> different terminology than what everyone else uses... I would really really
> like it if we used standard textbook terminology for these things.

I think I am using the term "Rule" standardly.... The ForwardInferenceStep,
as I defined it, involved

-- grabbing an Atom A from the AttentionalFocus

-- choosing a PLN Rule R to use

-- if the Rule R is unary (like inversion), applying it to A, and
putting the result into the Atomspace

-- if the Rule R is binary (like deduction) finding another Atom B
that is suitable, and applying R to A and B to get a result... and
putting the result in the Atomspace

...

So as you see the inference step is NOT just a logical rule...

It is a kind of atomic chunk of "control strategy", including
selection of a rule and of an Atom to go with the rule...


> OK, maybe you don't need the pattern matcher, but ... I don't understand.
> You keep talking about forward and backward chaining, and I keep saying
> that the pattern matcher is a forward chainer, and then you write "but it's
> not what we need..."
>
> This leaves me thoroughly confused. Do you need a forward chainer, or not?
> Because if you do, I've got one...

The pattern matcher is a pattern matcher. It's not a forward chainer.

The pattern matcher can be used *inside* a forward chainer..... It can be used
inside many different kinds of forward chainer...

I have a specific design for a PLN forward chainer, which can utilize
the pattern
matcher internally....

Perhaps other kinds of forward chainers could utilize the pattern matcher in
some more complex or thorough way...

I don't want a PLN forward chainer that [let's call this Chainer A]

-- starts with a list of rules

-- iterates through the list of rules, and applies them willy-nilly to
the Atomspace

-- back to the start

This would be the simplest form of standard "production system", but I
don't think it's the best way to do things in an AGI sy stem...

Rather, my forward chainer has an atomic step that (very roughly)

-- starts with an Atom (that it chose based on some heuristic)

-- chooses a Rule

-- chooses another Atom, and combines it with the original Atom using the Rule

-- back to the start

The forward chaining process then consists of applying this atomic step over
and over again. [let's call this Chainer B]

This may be done concurrently with applying an atomic backward inference
step over and over again; and with doing other stuff like spreading STI across
the Atomspace, etc. etc.

Perhaps part of the confusion in this dialogue is that when you say
"forward chainer" you are thinking strictly of a Chainer A type design, whereas
what I'm thinking about in a PLN context is now a Chainer B type design...



-- Ben

Linas Vepstas

unread,
Apr 27, 2013, 1:29:28 PM4/27/13
to Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org
Let me reply in two parts.


On 27 April 2013 01:34, Ben Goertzel <b...@goertzel.org> wrote:

>> 1)
>> DEDUCTION RULE SPECIFICATION
In the terminology used in PLN,

Inheritance A B
Inheritance B C
|-
Inheritance A C

yes, the above is a rule.

Well, in logic, things like

A
A -->B
|-
B

are generally called rules (e.g. Modus Ponens rule, etc.).   So I don't think
my terminology here is strange....  Rather, I suppose my writing was
somehow unclear, so that you misunderstood me...


Yes, that's a rule too.

Here is the source of the confusion. Its notational. Yes, the above are what I would call rules.  The problem arises when one writes something similar-looking, in C++ (or python, or scheme...)  I claim that those similar-looking things are no longer rules (even though they look very similar to rules); rather that they are (atomic) formulas (using the text-book definition of 'atomic formula').

So: a graph-rewriting rule is something of the form "when you find a pattern of shape A, replace it by a pattern of shape B".  Such a rule is meant to be applied to the current contents of the atomspace (by some applier that is capable of finding patterns of shape A, and then invoking the rule.)

This is not the same as the C++ code snippet

/* ha is a handle pointing at pattern A */
Handle f(Handle ha) {
    /*  create pattern B, return handle  hb pointing to pattern B */
   return hb;
}

I claim that f() above is not a "rule" because it is missing an important part of the rule: the part that is saying "when you find a pattern of shape A".  In C++, the argument ha already is pattern A; there is no 'finding' involved any more.  Its not a rule, its merely the atomic formula that defines pattern B.  (Which is why I want to call it a 'formula' and not a 'rule')

We agree about the 'inference step': the definition of an inference step is essentially a statement 'here is a bag of stuff, apply rule to all stuff that match the rule conditions'.

The only way, in C++, to do this is to write f() as a template, and have the compiler look at the 'bag of stuff' (the source code), and apply the template to all source code where the template fits.  The only rules in C++ are templates, and they are compile-time. There are no run-time rules in C++. In C++, the language itself, the only 'pattern matcher' is the compiler itself (gcc), and all pattern matching is done at compile-time, using C++ templates.   There is no support for run-time 'rules' in C++, and a subroutine/function in C++ could never be a rule.

Right? Should I repeat myself? A rule is a rule only if it can be applied to a bag of stuff by some applier.  In opencog, the 'bag of stuff' is the atomspace, the applier is the pattern matcher, and thus the only rules are those things that the applier knows how to apply.  The applier does not know how to apply C++ subroutines; subroutines cannot be rules.

The above is at the core of the confusion.  The distinction is important, I think one should be careful making the distinction.

--linas




Linas Vepstas

unread,
Apr 27, 2013, 2:28:44 PM4/27/13
to Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org
Hi Ben,

Regarding the actual programming of it all...

On 27 April 2013 01:34, Ben Goertzel <b...@goertzel.org> wrote:

Then this MindAgent would use the pattern matcher to launch a query

****
(define find-cats
  (BindLink
    ;; The variable to be bound
    (VariableNode "$var")
    (InheritanceLink

Umm, I'm pretty sure the above has to be an ImplicationLink, not an InheritanceLink. I'm not sure what would happen if it was an inheritance link. It might throw an error.
 
      ;; The pattern to be searched for
      (InheritanceLink
         (VariableNode "$var")
         (ConceptNode "cat")
      )

      ;; The value to be returned. 
      (VariableNode "$var")

Uhh, no.  Nothing is "returned".  It pattern matcher does not return things.

Recall that an ImplicationLink is in the form "if P then Q"    Above, the pattern P to search for was (Inheritance $var cat).  Q can either be another pattern, or an ExecutionLink.

If Q is a pattern then the pattern matcher creates Q and then moves on to the next match (if any).  

If Q is an ExecutionLink, then the pattern matcher executes the (scheme/python/C++/java) program specified by the GroundedSchemaNode, passing as arguments the rest of the ExecutionLink.   After doing the execution, it moves on to the next match (if any).

There is no return; at least, not until it has run out of things to do.
 

Then the forward chaining MindAgent would look at the truth values of
these links,

No, that's not how it works.  The pattern matcher *is* the forward-chainer. 

If you want to have some scheme/python/C++ code to look at truth values, and so something with them, then you must use an ExecutionLink, and provide the name of the scheme/python/C++ function in a GroundedSchemaNode.

Then, next cycle, the forward chainer would pluck another Atom out of the
AttentionalFocus (the set of Atoms with STI > AttentionalFocusBoundary),
and try the same thing over again.   

There is no "next cycle", because the pattern matcher does not 'return' in the sense that you used.   However, the above sentence is interesting anyway.  There are two different ways of achieving the intent of what you want above.

One way is to create a GroundedSchemeNode that examines the STI.  If STI is too small, do nothing.  This can be done today, quite easily; I suggested this as a homework exercise.

There is actually a second and very interesting way that this can be solved, but we can't discuss it till the above basic mis-understandings are cleared up.

It is a kind of atomic chunk of "control strategy", including
selection of a rule and of an Atom to go with the rule...

Covered in earlier e-mail. This is rooted in a mis-understanding. The pattern matcher *is* the "control strategy". 


The pattern matcher is a pattern matcher.  It's not a forward chainer.

Rooted in a mis-understanding.  You think that it is something other than what it is; it does not work the way you think it does.  It is a pattern-rewriting engine; essentially. it is a forward chainer.

It will be hard to continue talking until its clearly understood what the pattern matcher is, what it does, and how it works.

-- Linas

Ben Goertzel

unread,
Apr 28, 2013, 12:38:03 AM4/28/13
to linasv...@gmail.com, Ramin Barati, opencog, hk-a...@opencog.org
Linas,

About the terminological question of "what is an inference rule" ...

> Here is the source of the confusion. Its notational. Yes, the above are what
> I would call rules. The problem arises when one writes something
> similar-looking, in C++ (or python, or scheme...) I claim that those
> similar-looking things are no longer rules (even though they look very
> similar to rules); rather that they are (atomic) formulas (using the
> text-book definition of 'atomic formula').
>
> So: a graph-rewriting rule is something of the form "when you find a pattern
> of shape A, replace it by a pattern of shape B". Such a rule is meant to be
> applied to the current contents of the atomspace (by some applier that is
> capable of finding patterns of shape A, and then invoking the rule.)
>
> This is not the same as the C++ code snippet
>
> /* ha is a handle pointing at pattern A */
> Handle f(Handle ha) {
> /* create pattern B, return handle hb pointing to pattern B */
> return hb;
> }
>
> I claim that f() above is not a "rule" because it is missing an important
> part of the rule: the part that is saying "when you find a pattern of shape
> A". In C++, the argument ha already is pattern A; there is no 'finding'
> involved any more. Its not a rule, its merely the atomic formula that
> defines pattern B. (Which is why I want to call it a 'formula' and not a
> 'rule')

Well, a perusal of

http://en.wikipedia.org/wiki/Rule_of_inference

reveals that we are not the only folks who disagree about the precise
semantics of the term "rule" in a logic context...

At the top it says

"In logic, a rule of inference, inference rule, or transformation rule
is the act of drawing a conclusion based on the form of premises
interpreted as a function which takes premises, analyzes their syntax,
and returns a conclusion (or conclusions)."

So in this case the rule is the actual *action* ...

Further down, it says

"
Rules are statements ABOUT the system, axioms are statements IN the system.
"

Of course a statement about a system is not the same as an act of
drawing a conclusion...

I conclude that different people with expertise in the area construe
the semantics of concept of "rule" slightly differently, even though
everyone is talking about the same concrete examples (modus ponens,
term logic deduction, etc. etc.)

[Yeah, I know Wikipedia is not authoritative; it's just quick for me
to grab quotes from.... The same diversity in interpretation of the
semantics of "rule" exists throughout the philosophy of logic
literature...]

In the case of PLN, there is a series of publications which uses the
terms Rule and Formula as I have described.... I can see that the
term "Formula" may have been poorly chosen (I could perhaps have used
Equation instead, for instance), but I suspect that changing the term
for "PLN Truth Value Formula" to "PLN Truth Value Equation" now, would
add to, rather than subtract, confusion. (Because it would introduce
a terminological difference btw the theoretical publications and the
implementation.) ....

> We agree about the 'inference step': the definition of an inference step is
> essentially a statement 'here is a bag of stuff, apply rule to all stuff
> that match the rule conditions'.

Actually the "inference steps" in my new PLN design are a little more
than that...

The forward inference step I describe, for instance, is more like
"here is an Atom A, choose
a rule R and then find an Atom B and apply R to (A,B)"

I don't really care if this is called a "Step" or something else....
If you have another
term for this sort of "small chunk of controlled inference" I'm happy
to consider it...

> The only way, in C++, to do this is to write f() as a template, and have the
> compiler look at the 'bag of stuff' (the source code), and apply the
> template to all source code where the template fits. The only rules in C++
> are templates, and they are compile-time. There are no run-time rules in
> C++. In C++, the language itself, the only 'pattern matcher' is the compiler
> itself (gcc), and all pattern matching is done at compile-time, using C++
> templates. There is no support for run-time 'rules' in C++, and a
> subroutine/function in C++ could never be a rule.
>
> Right? Should I repeat myself? A rule is a rule only if it can be applied to
> a bag of stuff by some applier. In opencog, the 'bag of stuff' is the
> atomspace, the applier is the pattern matcher, and thus the only rules are
> those things that the applier knows how to apply. The applier does not know
> how to apply C++ subroutines; subroutines cannot be rules.
>
> The above is at the core of the confusion. The distinction is important, I
> think one should be careful making the distinction.

Hmmm.... But the snippet

> /* ha is a handle pointing at pattern A */
> Handle f(Handle ha) {
> /* create pattern B, return handle hb pointing to pattern B */
> return hb;
> }

can be applied to an Atom by a C++ function that applies f to a Handle that
it grabs from the Atomspace....

What you are saying is that C++ subroutines cannot be rules **relative to your
pattern matcher**, because your pattern matcher does not know how to
apply them....

But that does not imply that they cannot be rules (in the
sense of your definition of "rule") relative to some other applier,
such as a PLN
implementation...

I am curious what you would suggest to call a function such as

> /* ha is a handle pointing at pattern A */
> Handle f(Handle ha) {
> /* create pattern B, return handle hb pointing to pattern B */
> return hb;
> }

which embodies a PLN logic rule in the way it creates pattern B? If
it's not a rule,
in your vernacular, then what is it? A proto-rule?

My suggestion is that we clarify the issues regarding the PLN design
first, and then
if necessary return to these terminological issues...

I now understand much better what you mean by "rule" and why, which is useful,
so thanks...

While it seems that there is wide disagreement on the precise semantics of the
concept of "rule", it certainly is important for those of us working
together on OpenCog
to understand what each other are talking about...

I will reply to your other email about forward chaining etc. a little
later today... that is
the meatier one, and I know what I want to say, but need to wait till
I have a free half
hour to write something (hopefully) clear...

-- Ben

Ben Goertzel

unread,
Apr 28, 2013, 1:53:05 AM4/28/13
to linasv...@gmail.com, Ramin Barati, opencog, hk-a...@opencog.org
> What you are saying is that C++ subroutines cannot be rules **relative to your
> pattern matcher**, because your pattern matcher does not know how to
> apply them....
>
> But that does not imply that they cannot be rules (in the
> sense of your definition of "rule") relative to some other applier,
> such as a PLN
> implementation...

I mean... in the context of the C++ PLN implementation, there was no
intervening layer
between Rule objects containing methods roughly like

>> /* ha is a handle pointing at pattern A */
>> Handle f(Handle ha, Handle hb) {
>> /* create pattern C, return handle hb pointing to pattern C */
>> return hc;
>> }

and the PLN logic engine.... So it seems only sensible to say that
these Rule objects
were "rule" in your sense relative to the C++ PLN implementation as
the "applier"

It's true that C++, in itself, does not know how to apply these rules
(in the sense that it
would if they were written as C++ templates). But the C++ PLN engine
does know how
to apply those rules...

-- Ben

Ben Goertzel

unread,
Apr 28, 2013, 2:37:25 AM4/28/13
to linasv...@gmail.com, Ramin Barati, opencog, hk-a...@opencog.org
Linas,

On Sun, Apr 28, 2013 at 2:28 AM, Linas Vepstas <linasv...@gmail.com> wrote:
> Hi Ben,
>
> Regarding the actual programming of it all...

First I will reply to this email, then I'll write a separate email conveying
my thoughts about the PLN implementation, in the light of this discussion...

Sometimes I feel like the coherence of ideas gets lost in the
(valuable) back-and-forth
of discussion...

>> Then this MindAgent would use the pattern matcher to launch a query
>>
>> ****
>> (define find-cats
>> (BindLink
>> ;; The variable to be bound
>> (VariableNode "$var")
>> (InheritanceLink
>
>
> Umm, I'm pretty sure the above has to be an ImplicationLink, not an
> InheritanceLink. I'm not sure what would happen if it was an inheritance
> link. It might throw an error.

yeah, I screwed that example up, it should have been

****

(define find-cats
(BindLink
;; The variable to be bound
(VariableNode "$var")
(ImplicationLink
;; The pattern to be searched for
(InheritanceLink
(VariableNode "$var")
(ConceptNode "cat")
)
;; The value to be returned.
(VariableNode "$var")
)
)
)

****

I.e. the pattern being searched for involves an InheritanceLink (in
this example), but I understand the outer link describing the action
of the pattern matcher should always be an ImplicationLink...

>> ;; The pattern to be searched for
>> (InheritanceLink
>> (VariableNode "$var")
>> (ConceptNode "cat")
>> )
>>
>> ;; The value to be returned.
>>
>> (VariableNode "$var")
>
>
> Uhh, no. Nothing is "returned". It pattern matcher does not return things.

Ummm.... I pasted the phrase " ;; The value to be returned. " from the
example on the wiki page, which I assume you wrote...

Also, the section

http://wiki.opencog.org/wikihome/index.php?title=Pattern_matching&action=edit&section=1

refers repeatedly to what the pattern matcher returns... e.g.

"cog-bind will return a ListLink with the two groundings:" ,

"specify an ExecutionLink as the 'return value'. ",

etc.


> Recall that an ImplicationLink is in the form "if P then Q" Above, the
> pattern P to search for was (Inheritance $var cat). Q can either be another
> pattern, or an ExecutionLink.
>
> If Q is a pattern then the pattern matcher creates Q and then moves on to
> the next match (if any).
>
> If Q is an ExecutionLink, then the pattern matcher executes the
> (scheme/python/C++/java) program specified by the GroundedSchemaNode,
> passing as arguments the rest of the ExecutionLink. After doing the
> execution, it moves on to the next match (if any).

Understood, thanks...

>> Then the forward chaining MindAgent would look at the truth values of
>> these links,
>
>
> No, that's not how it works. The pattern matcher *is* the forward-chainer.

Well, the pattern matcher is not in itself, literally, a chainer....
Rather it carries
out a step. Multiple of these steps can be chained together, if that is what
you choose to do...

The pattern matcher, as you say, accepts inputs of the form

-- Implication P Q

and then searches for matches to P, and produces results matching Q,
based on the matches found for P

One could choose to have the system perform forward chaining via
repeatedly applying the pattern matcher

On the other hand, one could also implement a forward chainer separately,
e.g. in C++ or python, and have this separate forward chainer make calls
the pattern matcher for its own purposes, when it chooses to..

Both of these are viable options...

> If you want to have some scheme/python/C++ code to look at truth values, and
> so something with them, then you must use an ExecutionLink, and provide the
> name of the scheme/python/C++ function in a GroundedSchemaNode.

Actually this is only one design strategy, right?

For instance, the existing PLN implementations (in C++ and python) do NOT
work this way, and yet they still function and perform inferences...

What you are describing is the way to have scheme/python/C++ code inspect
and manipulate truth values, **within a framework where all the
chaining of inferences
is controlled within the context of your pattern matcher**

This is **a** way to do things in OpenCog. It might even be the best way.
But it's certainly not the only way...

>> Then, next cycle, the forward chainer would pluck another Atom out of the
>> AttentionalFocus (the set of Atoms with STI > AttentionalFocusBoundary),
>> and try the same thing over again.
>
>
> There is no "next cycle", because the pattern matcher does not 'return' in
> the sense that you used. However, the above sentence is interesting
> anyway. There are two different ways of achieving the intent of what you
> want above.
>
> One way is to create a GroundedSchemeNode that examines the STI. If STI is
> too small, do nothing. This can be done today, quite easily; I suggested
> this as a homework exercise.

Yes, this is clear...

>> It is a kind of atomic chunk of "control strategy", including
>> selection of a rule and of an Atom to go with the rule...
>
>
> Covered in earlier e-mail. This is rooted in a mis-understanding. The
> pattern matcher *is* the "control strategy".

Linas: One way to implement an inference control strategy is to use the
pattern matcher as the basic tool, and pack all the specific logic of one's
control strategy into GroundedSchemaNodes, which are then executed
via the pattern matcher via ExecutionLinks

However, this is not the ONLY possible or sensible way to do things
in OpenCog.... It's a specific strategy. And the pattern matcher may be
useful within other approaches as well...

>> The pattern matcher is a pattern matcher. It's not a forward chainer.
>
>
> Rooted in a mis-understanding. You think that it is something other than
> what it is; it does not work the way you think it does. It is a
> pattern-rewriting engine; essentially. it is a forward chainer.
>
> It will be hard to continue talking until its clearly understood what the
> pattern matcher is, what it does, and how it works.

I understand what the pattern matcher does...

I understand that one can do forward chaining via repeatedly applying the
pattern matcher

I understand that, within this framework, one can create a variety of
customized forward chaining schemes, via creating GroundedSchemaNodes
that implement one's customizations...

I do not think this is the *only* sensible way to do forward chaining in
OpenCog, though...

-- Ben

Ben Goertzel

unread,
Apr 28, 2013, 3:13:32 AM4/28/13
to linasv...@gmail.com, Ramin Barati, opencog, hk-a...@opencog.org
Linas,

> No, that's not how it works. The pattern matcher *is* the forward-chainer.
>

I see now that on the wiki page, you describe the pattern matcher as a
"one-step forward chainer" ...

This poses the philosophical question of whether a chain with only one
link is still a chain, I suppose ;p

I wasn't thinking about a one-step forward chainer as being a
chainer.... . I was thinking about it as being a STEP -- such that
multiple of these steps could be chained together to do forward
chaining, but such that the step could also be used in different
ways...

ben

Linas Vepstas

unread,
Apr 28, 2013, 9:05:20 PM4/28/13
to Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org
Hi Ben,


On 27 April 2013 23:38, Ben Goertzel <b...@goertzel.org> wrote:

http://en.wikipedia.org/wiki/Rule_of_inference

I think this argument is getting silly, so I will provide a short reply.   

In the case of PLN, there is a series of publications which uses the
terms Rule and Formula as I have described....

I have no beef with the wikipedia, article, or with your formal, abstract definition of rules and formulas.  However, calling a C++ function a "rule" confused me; and I'll stick to my guns there: its seems obviously wrong. The only "rules" in C++ are templates, and the only rule evaluation in C++ is necessarily at compile time, not at run time.   

 I can see that the
term "Formula" may have been poorly chosen (I could perhaps have used
Equation instead, for instance),

It is a formula, that name is fine.  Its not an equation. You could all it an assignment, if you wish, but equations are something else again:  equations only occur in relational algebras, and I don't see how computation of truth values turns into an relational algebra.

Essentially, I'm working with a model-theoretic definition of "formula":


For me, C++ functions are "terms"  viz f(x_1, ... x_n)   It doesn't matter whether x_1... x_n are truth values, or handles, or attention values.  The type of the arguments doesn't change what it is.  Its still a term, and thus is properly called a formula.

 
> /* ha is a handle pointing at pattern A */
> Handle f(Handle ha) {
>     /*  create pattern B, return handle  hb pointing to pattern B */
>    return hb;
> }

can be applied to an Atom by a C++ function that applies f to a Handle that
it grabs from the Atomspace....

Argh.  No, its not possible, not by C++.  You would have to write some sort of algorithm that would be able to search the atomspace, and perform the application.  C++ itself is not capable of doing application at run-time; it can only do application at compile time.
 
My suggestion is that we clarify the issues regarding the PLN design
first,

I have no problem calling A->B a rule and yes, "rule" is the appropriate name for this.  But calling C++ functions "rules" is just .. bizarre.  That's my primary complaint.

While it seems that there is wide disagreement on the precise semantics of the
concept of "rule",

No, there isn't.  I think we both agree as to what a rule is, in general: we agree that A->B is a rule. I think most of the world agrees on this, including virtually all wikipedia articles.  We just disagree as to whether f(A) is a rule. I think its misleading to call f(A) a rule.  Certainly, it mis-lead me.

Don't confuse C++ with Caml or haskell.  They're different.

--linas
 

Linas Vepstas

unread,
Apr 28, 2013, 9:16:54 PM4/28/13
to Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org
I've nothing to add to the conversation below, I agree with everything you said.  

Part of the problem is that there are multiple, different-but-related things called "the pattern matcher", and you focused on one while I focused on another. I think we are in agreement. I do have to expand some wiki-pages though.

--linas

Ben Goertzel

unread,
Apr 28, 2013, 9:17:49 PM4/28/13
to ope...@googlegroups.com, Ramin Barati, hk-a...@opencog.org
Hi Linas,

>> > /* ha is a handle pointing at pattern A */
>> > Handle f(Handle ha) {
>> > /* create pattern B, return handle hb pointing to pattern B */
>> > return hb;
>> > }
>>
>> can be applied to an Atom by a C++ function that applies f to a Handle
>> that
>> it grabs from the Atomspace....
>
>
> Argh. No, its not possible, not by C++. You would have to write some sort
> of algorithm that would be able to search the atomspace, and perform the
> application. C++ itself is not capable of doing application at run-time; it
> can only do application at compile time.

Yeah, the C++ PLN system is an algorithm that searches the atomspace,
and performs
the application!

> I have no problem calling A->B a rule and yes, "rule" is the appropriate
> name for this. But calling C++ functions "rules" is just .. bizarre.
> That's my primary complaint.

I Googled "C++ rule engine" and came across a number of other examples
of people using a similar naming convention in C++, e.g. (at random)

http://code.google.com/p/fuzzylite/downloads/detail?name=fuzzylite-2.0b1302-src.zip

has a class Rule.cpp which is instantiated to represent various fuzzy
logic rules.... They then have an Engine.cpp that interprets their
rules...

So it seems my naming choice really was not so odd in terms of common
practice...

-- Ben

Linas Vepstas

unread,
Apr 29, 2013, 12:58:31 AM4/29/13
to opencog, Ramin Barati, hk-a...@opencog.org
Ben,

Stop quibbling. These are all written in C++, they are not a part of the C++ language itself.  Unlike haskell, caml or lisp, C++ does not allow you to have your cake and eat it too.




-- Ben

--
You received this message because you are subscribed to the Google Groups "opencog" group.
To unsubscribe from this group and stop receiving emails from it, send an email to opencog+u...@googlegroups.com.
To post to this group, send email to ope...@googlegroups.com.
Visit this group at http://groups.google.com/group/opencog?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.



Linas Vepstas

unread,
Apr 29, 2013, 1:17:25 AM4/29/13
to Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org
Anyway ...

I expanded the wiki page http://wiki.opencog.org/w/Pattern_matching to explain what  the thing actually does, and what the available programming interfaces are. 

The engine itself is policy-free.  So far, only two policies have been implemented; BindLink implements one policy, the one I've been pushing you to look at.  There's  another: 'crisp-bind-link', which is very similar but allows for pattern rejection (i.e. you can ask for everything that has this, but not that in it). I needed it for NLP to look at only those sentences which did *not* have certain clauses in them.  You may need something similar.  The problem with this 'negation policy' is that you have to be careful to decide what "not" means (w.r.t. truth values).

I was pushing you to use BindLink because (I think) the ExecutionLink provides a great way of implementing policy, and PLN seems to be 90% policy and 10% algorithm.  However, as you review the new, improved wiki page, hopefully you'll see that there are other way of implementing policy.

I hope it's clear here what I mean by "policy".  In case its not, what I mean is this:  a "policy" is something that says "in situation X, do Y".   Good algorithms have little or no policy in them, because there are millions of policies, and no two dad-gummed users ever seem to want the same ones.  So let them hang, and write something generic, and allow the users to define whatever policies they feel like.  The engine provides the policy-free part, and the BindLink provides a useful, practical policy that should keep most users happy.

I'd like to move the conversation past this point, now.

-- Linas



Lake Watkins

unread,
Apr 29, 2013, 2:30:14 AM4/29/13
to Linas Vepstas, Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org
Well I don't know 'bout you two youngin's, but in my day we had just one "policy" and that was to treat others how we'd want 'em to treat ourselves.  If I recall, there was some dad-gummed, old book with some other MOSES and RedC that said some'n similar in it, but I figure you two already know 'bout that considerin' all the fancy words you be throwin' around.  

Speakin' of which, the way I reckon the two of you've written a veritable novel this past week 'bout all these highfalutin notions you've been havin'.  Now don't get me wrong, I surely do appreciate you takin' the time to spell everything out for an old southern fart like me, but when I see such noble ideas brought low by senseless name-callin' it really jerks a tear from my eye.  I ain't namin' any names, but I can certainly agree that movin' forward is a great direction.

So I took a gander at the link on links over yonder and I'm still not sure I've got a handle on it just yet.  I got a sneakin' suspicion that this C++ could do the job, but I make it a point not to trust no-one that's got 'double-cross' right in their name.  Haskell sounds like a warm, fuzzy feller though, and I'd be mightily inclined to listen to him over some'n's caml or his brother with a lisp.  That's just some weird shit right there.

I been seein' a pattern in this project of moving onward and upward, thanks to both you's hard work, which surely gives me hope even when the cake is a lie.  I encourage you to take another step in your forward-chainers and allocate some attention to how we'll all be workin' on this together.  I know I will.

Regards,
-Lake

Ben Goertzel

unread,
Apr 29, 2013, 3:24:37 AM4/29/13
to linasv...@gmail.com, Ramin Barati, opencog, hk-a...@opencog.org
Linas,

Thanks for the updated webpage!

One thing I learned from it is that, to make the PLNForwardStep (as
I'm conceiving it) utilize your pattern matcher, we would need to make
a custom class called

class PLNForwardStepPatternMatchCB

or some such (implementing PatternMatchCallback). This custom
callback would involve a customization of the

perform_search()

callback.... The customized perform_search would perform a random
selection from the Atomspace....

In this way, it seems one could implement a PLNForwardStep using the
pattern matcher with the implication

BindLink
VariableNode $A
ImplicationLink
EvaluationLink inAttentionalFocus $A
ExecutionLink PLNForwardStep $A

and using a customized perform_search that, given P==>Q, randomly
chooses a single entity satisfying P.

However, I remain unsure this is really the best way to do things in
this case...

On the other hand, it is VERY clear to me that the pattern matcher
will be extremely useful in the guts of a PLN backward chainer.
Because there we will have situations where we have a conjunction of N
different links, sharing M variables (with various links sharing
various variables with each other), and we want to find instantiations
for the M variables that work for all N links...

I will think on it more...

-- Ben



On Mon, Apr 29, 2013 at 1:17 PM, Linas Vepstas <linasv...@gmail.com> wrote:

Linas Vepstas

unread,
Apr 29, 2013, 10:00:11 AM4/29/13
to Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org

Hi,

On 29 April 2013 02:24, Ben Goertzel <b...@goertzel.org> wrote:
Linas,

class PLNForwardStepPatternMatchCB

This would certainly provide the greatest flexibility. 

In this way, it seems one could implement a PLNForwardStep using the
pattern matcher with the implication

BindLink
    VariableNode $A
    ImplicationLink
       EvaluationLink inAttentionalFocus $A
       ExecutionLink PLNForwardStep $A

With a customized matcher, you don't have to call it BindLink, or restrict yourself to ImplicationLink.  It could be anything. You don't even have to declare the VariableNodes.  As long as you can provide (in C++) a list of variables (which don't have to actually be VariableNodes, but could be any nodes) and a list of clauses, you are good to go.

On the other hand, it is VERY clear to me that the pattern matcher
will be extremely useful in the guts of a PLN backward chainer.
Because there we will have situations where we have a conjunction of N
different links, sharing M variables (with various links sharing
various variables with each other), and we want to find instantiations
for the M variables that work for all N links...

Yes. This is the primary problem which it solves.  If you have only one clause, and that clause is just a single link, you don't need the pattern matcher, since the search will never become complicated enough to require back-tracking.    Its the back-tracking, the ability to spider across any arbitrarily complicated graph, without restrictions, that is the core strength/function.

I'm unclear about what this M/N thing has to do with forward/backward chaining; why would the forward chainer only do simple things, and the backward one only hard things?

Anyway .. next topic(s): inference upon creation, and user-defined indexes.  

One problem with running inference is that it can be slow.  One reasonable solution to this is to trigger inference only when atoms are added to the atomspace.   That is, there would be a list of inference rules, and when that atom is added, each rule would get a shot at it, to see if it can now infer something from it.  I think this could overcome some of the bottlenecks of inferencing.  (The above is essentially a variant of the RETE algo).

A closely related idea is that of building user-defined indexes.  Again, there would be a list of rules that get run when an atom is added to the atomspace.  But instead of performing an inference, these would simply add to an index if there is a match.  Then, later on, if you wanted to get all graphs shaped like X in the atomspace, you could get them 'instantly', as they would all be in the index.  

(a true textbook-style RETE algo would maintain indexes for partial clause matches; inference triggers only when the final clause is matched.)

Its not clear to me if these would be interesting to you for PLN; I mention them because they might be, and because they should be reaonably straight-forward to implement.

-- Linas

Ben Goertzel

unread,
Apr 29, 2013, 10:16:24 AM4/29/13
to linasv...@gmail.com, Ramin Barati, opencog, hk-a...@opencog.org
Linas,

> Yes. This is the primary problem which it solves. If you have only one
> clause, and that clause is just a single link, you don't need the pattern
> matcher, since the search will never become complicated enough to require
> back-tracking. Its the back-tracking, the ability to spider across any
> arbitrarily complicated graph, without restrictions, that is the core
> strength/function.

Understood!

> I'm unclear about what this M/N thing has to do with forward/backward
> chaining; why would the forward chainer only do simple things, and the
> backward one only hard things?

Because in forward chaining, each step can be considered locally. You
can just go from a couple premises to a conclusion, and put the conclusion
in the Atomspace, and be done with it.... There is a clear application of the
pattern matcher here -- to find a suitable second premise, once one has chosen
a first premise and an inference rule -- but, it's a pretty simple
application, for
which the pattern matcher is a nice-to-have rather than a must-have..

On the other hand, in backward chaining, you are dealing constantly
with *hypotheticals* ---- I could conclude X, **if** I could derive
both Y and Z....
One arrives at an increasing list of interdependent hypotheticals, each of
which becomes represented as one or more variables... and then one has to
figure out if there's some way to satisfy all the hypotheticals at
once with a single
set of variable instantiations. This is a perfect application for a
single step of
the pattern matcher (i.e. each nontrivial step of PLN backward
chaining will induce a new
application of the pattern matcher).... Here the pattern matcher is a
must-have...

> One problem with running inference is that it can be slow. One reasonable
> solution to this is to trigger inference only when atoms are added to the
> atomspace. That is, there would be a list of inference rules, and when
> that atom is added, each rule would get a shot at it, to see if it can now
> infer something from it. I think this could overcome some of the
> bottlenecks of inferencing. (The above is essentially a variant of the RETE
> algo).

I think this approach is intrinsically not scalable to AGI.... Too many Atoms
will be added from perception of a virtual world, let alone the physical world
perceived by a robot.... It's not viable to have every rule match
every incoming
perception...

I am familiar with RETE and its use in SOAR and other similar cognitive
architectures, but I never considered that sort of approach terribly
promising for
AGI...

That said, I'm certainly not opposed to having someone else experiment
with that in OpenCog ;) ...

> A closely related idea is that of building user-defined indexes. Again,
> there would be a list of rules that get run when an atom is added to the
> atomspace. But instead of performing an inference, these would simply add
> to an index if there is a match. Then, later on, if you wanted to get all
> graphs shaped like X in the atomspace, you could get them 'instantly', as
> they would all be in the index.

Yes, we will need that in OpenCog, certainly.... There will only be
a short list of
index-building rules, so this shouldn't be too much of a drain on the system...

> (a true textbook-style RETE algo would maintain indexes for partial clause
> matches; inference triggers only when the final clause is matched.)

I don't think that is adequately scalable either...

> Its not clear to me if these would be interesting to you for PLN; I mention
> them because they might be, and because they should be reaonably
> straight-forward to implement.

I appreciate the suggestions! But my vision of PLN inference control is fairly
centered on use of STI values, as these let PLN be coupled with the nonlinear
dynamics of the ECAN attention allocation systems. I believe this coupling will
provide an agility and scalability that classical production system
architectures
don't have.... Of course, this is an unproven research conjecture at
this point,
though I think the arguments for it are very plausible...

-- Ben

Linas Vepstas

unread,
Apr 29, 2013, 11:33:12 AM4/29/13
to Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org
Hi,

On 29 April 2013 09:16, Ben Goertzel <b...@goertzel.org> wrote:

> I'm unclear about what this M/N thing has to do with forward/backward
> chaining; why would the forward chainer only do simple things, and the
> backward one only hard things?

Because in forward chaining, each step can be considered locally.  You
can just go from a couple premises to a conclusion, and put the conclusion
in the Atomspace, and be done with it....  

Hmm. OK.  My experience of trying to extract concepts from English lead me to some rather complicated forward-chains, pulling out stuff from a jumble of relex relations.  e.g. if there was a subject and an object (which have a verb in common) and there was a preposition, and the proposition was X and the prepositional object was Y ... I quickly ran into situations where I had 3,4,5 variables and 3,4,5 clauses that intertwined in complicated ways.   Even worse, I promptly ran into the case of having to *reject* certain patterns, e.g. match subject, verb, object, but only if there is NO attached preposition ... 

I strongly suspect that anyone who fiddles with the contents of some web-based triple-store or concept-net or frame-net-like things will promptly discover a need to handle complex forward-chaining constructions.

Here is another way to illustrate it: I also discovered that its impossible to "compress" English.  That is, if an english sentence is "subject verb object preposition prepostional-object"  then trying some slight-of-hand inference to boil this down into something shorter/simpler is not possible.  The structure is critical for understanding the meaning.   Examples from Aristotelian logic are very misleading as to complexity:  "all cats are animals and Bjork is a cat, therefore Bjork is an animal."  seems real easy.   But I promptly hit this:   "The red box is on top of the blue box, and the blue box is next to the green fountain..."  and it turned out you cant't just ignore "blue" in the above, nor can you ignore "next to", "on top of". Replacing "the" by "a" changes the meaning entirely.  etc. So reasoning with the above promptly lead to expressions with more than half-a-dozen variables and a dozen clauses.  It became intractable, fast.  The good news was: 1) I learned something 2) multiple bugs in the pattern matcher got fixed.

Moral of the story: beware complexity.  IsA, hasA relations are the tip of the iceberg, and are highly misleading with regard to complexity.

-- Linas
  

Ben Goertzel

unread,
Apr 29, 2013, 12:31:16 PM4/29/13
to linasv...@gmail.com, Ramin Barati, opencog, hk-a...@opencog.org
Hmmm..

> Hmm. OK. My experience of trying to extract concepts from English lead me
> to some rather complicated forward-chains, pulling out stuff from a jumble
> of relex relations.

...

> The structure is critical for understanding the meaning. Examples from
> Aristotelian logic are very misleading as to complexity: "all cats are
> animals and Bjork is a cat, therefore Bjork is an animal." seems real easy.
> But I promptly hit this: "The red box is on top of the blue box, and the
> blue box is next to the green fountain..." and it turned out you cant't
> just ignore "blue" in the above, nor can you ignore "next to", "on top of".
> Replacing "the" by "a" changes the meaning entirely. etc. So reasoning with
> the above promptly lead to expressions with more than half-a-dozen variables
> and a dozen clauses. It became intractable, fast. The good news was: 1) I
> learned something 2) multiple bugs in the pattern matcher got fixed.


Ok, taking the example you've just given the output of Syn2Sem will be
something like...

EvaluationLink
atop
SpecificEntityNode B1
SpecificEntityNode B2

EvaluationLink
next_to
SpecificEntityNode B2
SpecificEntityNode G1

InheritanceLink B1 red
InheritanceLink B1 box
InheritanceLink B2 blue
InheritanceLink B2 box
InheritanceLink G1 green
InheritanceLink G1 fountain

if there is knowledge

AverageQuantifier
VariableNode $v1 $v2
ImplicationLink
Evaluation atop $v1 $v2
Evaluation near $v1 $v2

AverageQuantifier
VariableNode $v1 $v2
ImplicationLink
Evaluation next_to $v1 $v2
Evaluation near $v1 $v2



then the conclusion

EvaluationLink
near
B2 G1

can be drawn by a few PLN ForwardInferenceSteps, according to the
scheme I've described... so long as the initially given Atoms
resultant from Syn2Sem all have high enough STI to be in the
Attentional Focus...

PLN elegantly breaks down complex inferences into very simple steps...

-- Ben

Linas Vepstas

unread,
Apr 29, 2013, 1:40:30 PM4/29/13
to Ben Goertzel, Ramin Barati, opencog, hk-a...@opencog.org
On 29 April 2013 11:31, Ben Goertzel <b...@goertzel.org> wrote:
Hmmm..

> Hmm. OK.  My experience of trying to extract concepts from English lead me
> to some rather complicated forward-chains, pulling out stuff from a jumble
> of relex relations.

[...] 

can be drawn by a few PLN ForwardInferenceSteps, according to the
scheme I've described... so long as the initially given Atoms
resultant from Syn2Sem all have high enough STI to be in the
Attentional Focus...

PLN elegantly breaks down complex inferences into very simple steps...

Hmm. I'll believe it when I see it.  Maybe my example was poor; I made it up for this email.  The actual examples from the chatbot are below.  The "examples that work" are easy.   The "untested, probably don't work"  examples should also be easy, except that they would have needed additional inference rules to understand that a "who" is not a "what", that a "where" is like a "when" but the location is in space, not time .. etc.  Each of these required adding one or two more hand-written inference rules ... 

Writing one or two inference rules is "easy".  Writing 10 or 20 is "not hard".  But when you start trying to deal with all of English, and start counting how many inference rules are needed ... so, for example, one for each pair of prepositions. But there are hundreds of prepositions.   Some are very abstract.  "next to" is an easy spatial relationship.  "capital of" is a complex geo-political relationship.  So: "Germany is next to the country whose capital is Paris" might be somewhat do-able, but "Germany's capital is far from the centers of power in Brussels"  is not a statement about physical distance, but about political distance...

When I realized I had to write hundreds, or thousands, or more inference rules, then I gave up.  So when you say "PLN elegantly breaks down complex inferences into very simple steps..." ... well ... so did the chatbot.  But that's not the hard part.

But before I get to that, here's one thing I discovered. When you write

     InheritanceLink B1 red
     InheritanceLink B1 box

I tried something like that too, and quickly learned that it only sort-of works.  The problem is that "red" is a color; colors are not shapes (e.g. round ball) and although both appear to be adjectives modifying nouns, they are in different semantic categories  (things can be red and blue, they can't be round and square).  It spirals out of control once you try to get past the basics.

Anyway, below was the progress report from back then. Again, the easy things are beguilingly easy.  But they are the tip of the iceberg.

(There was no sentence generation, so the responses are just yes/no, or the root verb of a responding sentence, or the entity for entity questions)

 Examples:
---------
<me>         Fred threw a red ball
<me>         John threw a green ball.
<me>         Mary threw a blue rock
<me>         who threw a ball?
<cogita-bot> SVO pattern match found: John Fred
<me>         who threw a red ball?
<cogita-bot> SVO pattern match found: Fred
<me>         What did Fred throw?
<cogita-bot> SVO pattern match found: red ball

<me>         Did Fred throw a ball?
<cogita-bot> Truth query determined: Yes, verb was: throw

<me>         Did Fred throw a red ball?
<cogita-bot> Truth query determined: Yes, verb was: throw
<me>         Did Fred throw a green ball?
<cogita-bot> Truth query determined: No, not that I know of. 

<me>         The color of the book is red.
<me>         What is the color of the book?
<cogita-bot> Triples abstraction found: red

<me>         the cat sat on the mat
<me>         what did the cat sit on?
<cogita-bot> Triples abstraction found: mat

<me>         John and Berd turned into monsters
<me>         who turned into monsters?
<cogita-bot> Triples abstraction found: John Berd Berd John

<me>         John made fun of Sarah.
<me>         Who made fun of Sarah?
<cogita-bot> SVO pattern match found: John

Some things that don't work:
"Did Fred throw a round ball?" -- doesn't know that balls are round.

Untested, probably won't work:
 * truth-query w/ preps: Is Berlin the capital of Germany?
 * Do questions (What did Mike do? Mike threw a rock)
 * Who died?    (John Kennedy died)
 * Did John die?
 * John is dead?
 * Who is Kennedy?
 * What is yarn?
 * When questions.
 * Where questions.
 * Why questions.
 * How questions
 * How-much questions (how-tall, how-safe etc)
 * Which questions

 * The red ball is under the couch. Where is the red ball?
   The RelEx coding is correct, the output is not.



Ben Goertzel

unread,
Apr 30, 2013, 11:34:22 AM4/30/13
to ope...@googlegroups.com, Ramin Barati, hk-a...@opencog.org
Linas,

yeah, there are some difficult problems here, and PLN in itself
certainly doesn't solve all of them -- though I hope it can be an
ingredient of the solution...

The PLN inference rules are simple enough, and are complete in a
logical sense, but they don't embody all commonsense knowledge,
obviously...

To draw commonsense conclusions regarding natural language sentences,
one needs loads of commonsense knowledge...

For instance, consider the sentences

-- I went to the store with my friend

-- My friend and I went to the store

Even if Syn2Sem works as well as Ruiting and I are hoping, it's going
to map these two sentences into pretty different-looking Atom-sets....
To map between these requires some common-sense knowledge about what
"with" means in this context....

RelEx2Frame tried to solve this problem, but failed... and to try to
really make it work would have probably let to a Cyc-like expansion of
hand-coded rules

Hypothetically one could learn the needed commonsense knowledge
"rules" from large-scale unsupervised text mining.... Mike Ross and
I had some plans for this, based on extending Dekang Lin's work, back
in 2005 or so ... as you'll recall...

My current hope is to teach OpenCog this sort of commonsense knowledge
via (virtually and/or robotically) embodied experience that involves
communication with (initially) simple sentences.... But this of
course is a difficult research project as well.... I hope PLN can be
helpful with this sort of learning...

-- Ben
> --
> You received this message because you are subscribed to the Google Groups
> "opencog" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to opencog+u...@googlegroups.com.
> To post to this group, send email to ope...@googlegroups.com.
> Visit this group at http://groups.google.com/group/opencog?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>



Linas Vepstas

unread,
Apr 30, 2013, 2:26:56 PM4/30/13
to Ben Goertzel, opencog, Ramin Barati, hk-a...@opencog.org
Hi Ben,

On 30 April 2013 10:34, Ben Goertzel <b...@goertzel.org> wrote:
Linas,

yeah, there are some difficult problems here, and PLN in itself
certainly doesn't solve all of them -- though I hope it can be an
ingredient of the solution...

The PLN inference rules are simple enough, and are complete in a
logical sense, but they don't embody all commonsense knowledge,
obviously...

Well, it occurred to me that  perhaps you were embarking on an exercise in "premature optimization".  There are really three tasks:

1) Get basic PLN to work
2) Get PLN to work efficiently and rapidly and elegantly
3) learn commonsense knowledge.

All of the talk about attention allocation & etc. is really about issue (2)  but right now, issue (2) is not what is holding back opencog; its really (1) and (3).   Someday, (2) will be a problem, but it just doesn't seem to be important (to me) right now.  So don't  over-design it -- after you get (3) working, you might realize that PLN has to be completely redesigned anyway (not the theory, but the code).  Careful investing in what may become a throw-away ... 

For instance, consider the sentences

-- I went to the store with my friend

-- My friend and I went to the store

Even if Syn2Sem works as well as Ruiting and I are hoping, it's going
to map these two sentences into pretty different-looking Atom-sets.... 
 To map between these requires some common-sense knowledge about what
"with" means in this context....

 
Yes. Many years ago, I tripped over this same problem; my canonical example of it in the emails and readme's had to do with 'yarn being made of wool.' or something like that.  In those emails, I'd been calling this the "normalization" problem, of trying to reduce both sentences to a common normal form.

Its not just an "equivalence" problem, of knowing these two carry (almost) the same information; its harder: if you heard the first sentence, and remembered it in memory, and later hear the second sentence, you have to convert the second sentence to whatever is stored in memory, if you are to find the equivalence.  Thus, memory stores the "normalized" form. 

Anyway, I think I know how to solve it.

Hypothetically one could learn the needed commonsense knowledge
"rules" from large-scale unsupervised text mining....    Mike Ross and
I had some plans for this, based on extending Dekang Lin's work, back
in 2005 or so ... as  you'll recall...

You should recall that I greatly expanded this proposal, back when.  The key was the discovery of a large generalization of Dekang Lin's work.  Lin only explained how to discover synonyms, using a simple, but workable and easy to understand and easy to implement algorithm.  But one can go considerably farther: the method generalizes to arbitrary hypergraphs, instead of just  neighboring word-pairs.  The generalization was developed by Hoifung Poon + Pedro Domingos in their USP parsing system.  Its considerably more abstract and harder to understand than Lin's work.  But it is, I believe, the more-or-less correct generalization.   I also think I know how to do the Poon & Domingos trick in a simpler, faster way, without loosing generality.

Let me be clear: Poon & Domingos describe a general algorithm for solving the "equivalence"/"normalization" problem.  They implement some code, and show that it works for some certain examples.

I tried to write up this proposal in /opencog/nlp/lexical-attraction/README  but eventually ran out of time and had to put it down.  I still think about it:  one of the side-effects was that I convinced myself that I needed to have the Viterbi parser to get this work; that viterbi that is integrated in with opencog is a pre-requisite.

=======

The other thing I learned is that applying certain manual normalization steps, such as converting "red box" to (Inheritance entity-B2 "box") (Inheritance entity-B2 "red")  throws away too much important information.  This is what all that chatter about  SVO normalization way back when was all about: I already made a very similar mistake, and it was difficult to unwind because it was embedded deep into the system.  I convinced myself that you really really do have to maintain  surface-syntactic info, shallow linguistic info, and you have to *add* to it, slowly supplant it, rather then replace it by "obvious" generalizations; the "obvious generalizations" discard important information.  

What this means, in practical terms, for Syn2Sem, is that you want to take the (surface) parse graph, and decorate it with additional relationships, additional abstract knowledge.  You do not want to replace the parse graph with something more abstract: replacing is a mistake.   By enhancing the the graph with additional knowledge, the common-sense reasoners (PLN, whatever) can then use the abstract representation, if desired, but can also make use of the the less-abstract structure to resolve ambiguities e.g. with (Inheritance entity-B2 "red") to observe that "red" really was an adjectival modifier.

viz (perhaps maybe a bad example): but  (Inheritance entity-B2 "box") (Inheritance entity-B2 "red")  might be a "red box" but it might also be a (white) box filled with red paint.  Being able to go back and double-check the surface structure can be important for deducing/inferencing/learning the real meaning.  Discarding the surface structure, and replacing it with the abstract structure is a mistake.   I made that mistake already. Don't repeat it.

Ben Goertzel

unread,
Apr 30, 2013, 10:42:25 PM4/30/13
to linasv...@gmail.com, opencog, Ramin Barati, hk-a...@opencog.org, Shujing Ke
Hi Linas,

> Well, it occurred to me that perhaps you were embarking on an exercise in
> "premature optimization". There are really three tasks:
>
> 1) Get basic PLN to work
> 2) Get PLN to work efficiently and rapidly and elegantly
> 3) learn commonsense knowledge.
>
> All of the talk about attention allocation & etc. is really about issue (2)

I don't think about it that way... I think about integrating PLN and attention
allocation as part of the task "get the core of artificial cognition
to work" ...

I.e., integrating attention allocation and PLN is not so much about
efficiency optimization (except in the sense that all AI is about efficiency
optimization), as it is about making PLN actually smart enough to do anything
useful on real-world data... be that data linguistic or
virtual-world-based or whatever...

>> Hypothetically one could learn the needed commonsense knowledge
>> "rules" from large-scale unsupervised text mining.... Mike Ross and
>> I had some plans for this, based on extending Dekang Lin's work, back
>> in 2005 or so ... as you'll recall...
>
>
> You should recall that I greatly expanded this proposal, back when. The key
> was the discovery of a large generalization of Dekang Lin's work. Lin only
> explained how to discover synonyms, using a simple, but workable and easy to
> understand and easy to implement algorithm. But one can go considerably
> farther: the method generalizes to arbitrary hypergraphs, instead of just
> neighboring word-pairs. The generalization was developed by Hoifung Poon +
> Pedro Domingos in their USP parsing system. Its considerably more abstract
> and harder to understand than Lin's work. But it is, I believe, the
> more-or-less correct generalization. I also think I know how to do the
> Poon & Domingos trick in a simpler, faster way, without loosing generality.
>
> Let me be clear: Poon & Domingos describe a general algorithm for solving
> the "equivalence"/"normalization" problem. They implement some code, and
> show that it works for some certain examples.
>
> I tried to write up this proposal in /opencog/nlp/lexical-attraction/README
> but eventually ran out of time and had to put it down. I still think about
> it: one of the side-effects was that I convinced myself that I needed to
> have the Viterbi parser to get this work; that viterbi that is integrated in
> with opencog is a pre-requisite.

I remember this line of thinking/research, and I think it has
promise... and I think that Shujing's proposed hypergraph mining work
should be very helpful for this.... Hopefully it will be done by the
fall -- now she's trying to get her planner finished, and she'll start
on that afterwards...

> What this means, in practical terms, for Syn2Sem, is that you want to take
> the (surface) parse graph, and decorate it with additional relationships,
> additional abstract knowledge. You do not want to replace the parse graph
> with something more abstract: replacing is a mistake.

Yeah, I agree...

We want to have both the syntactic links AND the semantic links in the
Atomspace,
with appropriate linkages between them....

-- Ben
Reply all
Reply to author
Forward
0 new messages