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