Hi Michele,

On Fri, Aug 27, 2021 at 11:58 AM Michele Thiella <[email protected]>
wrote:

>
> - I tried to use StateLink
>
...

> backward chaining
>
...

Yes, StateLink is useless with backwards-chaining.  It can only work with
forward-chaining.


> - pushing / popping atomspaces:
> that's essentially what I'm doing now.
> Model-based rules all work well. So I copy the current atomspace into a
> "temporary" one,
>

A minor performance note: using push/pop might be slightly faster, by
avoiding a copy. (you can also manually push/pop with cog-new-atomspace,
cog-set-atomspace! and stuff like that.)


> The algorithm is a bit heavy and the tree explodes quickly but it is
> conceptually correct and working.
>

This is a generic problem with backwards-chaining: the algorithms are
heavy, slow, and have combinatoric explosions.  This has been known since
the 1980's and has been the subject of extensive academic research, and, no
doubt, dozens of PhD thesis.

This is why I keep yabbering about answer-set programming (ASP) and the
Univ. Potsdam ASP solver. Because ASP uses a SAT solver under the covers,
much or most or all of the combinatoric explosion can be avoided.  Or
rather, the SAT solvers prune the graph in such a way that the explosion is
avoided.

Exactly how to make use of this whiz-bang technology in the AtomSpace
remains an open research question.


> I don't think I understand the application of modal logic (for lack of
> knowledge I think)
>

Backwards chaining is a special case of modal logic.

Very roughly, modal logic is about reasoning over beliefs (If John believes
X, then John should also believe Y" ... or rather "it is possible that John
believes X, in which case, it is necessarily true that John believes Y") --
it is a form of reasoning over possible universes, where certain facts end
up being necessarily true.

The backwards-chaining variant of this is "if block X is on top of block Y,
then it is necessarily the case that Y is on top of the table or that Y is
on top of Z" and backwards chaining is just "find all possible universes
where block X is on top". (replace "John believes X" with "X is on top";
the "possible universes" are those where the block stack correctly.)

There was some GSOC summer-school effort to map the URE to modal logic, but
it wasn't accomplished.


But following one of the examples of the link:
> https://wiki.opencog.org/w/RelEx2Logic_representation
>
> "The book is on the table." not create the atom
> (EvaluationLink
>    (PredicateNode "on@903a1a18-124d-498d-97af-447277a798e5" )
>    (ListLink
>       (ConceptNode "book@12357525-7ca9-4d5e-85f8-b565228459aa")
>       (ConceptNode "table@be0f51a3-a7a0-400e-80ea-9ca860928af4")))
>
> Or rather, it creates it. But the ListLink contains only the table ... why?
>

I assume it's just a bug. The R2L code does not have an active maintainer.
Open a bug report. I'll look at it. If it's real easy, I'll try to fix it.
I hope it will be easy, and not some ugly mess.

-- Linas

>
> Il giorno venerdì 27 agosto 2021 alle 17:51:46 UTC+2 linas ha scritto:
>
>> Hi Michele!
>>
>> A quick reply to your last email.
>>
>> -- What Adrian said: yes, one should always begin by running rules one at
>> a time, by hand, to see what happens, after each one is run.
>>
>> -- "immutable" is not quite the right word. The atomspace is a
>> "blackboard": you can write on it, and you can erase (portions of) it, but
>> you cannot change what is written on it, without erasing first.
>>
>> -- Some AI textbooks use the word "blackboard".  This is the same thing.
>>
>> -- Given what you wrote below, it sounds like you had state management
>> problems.  For example, while stacking blocks, perhaps there were some
>> other left-over stacks from earlier attempts, that ruined the logic?
>> Perhaps you stored info that said the robot arm is both empty, and holding
>> something? Of course, it can't be both, but the atomspace doesn't know, and
>> you have to manage that state, explicitly.
>>
>> -- There are three ways to do this: with StateLink, by pushing/popping
>> atomspaces, and "ad hoc".
>>
>> -- The StateLink is a tool for atomic erase-and-write.  For example
>>
>> (State (Concept "robot arm") (Concept "empty"))
>>
>> can denote an arm that is not holding anything.   Later on, if you create
>> the atom
>>
>> (State (Concept "robot arm") (Evaluation (Predicate "holding") (Concept
>> "block 42")))
>>
>> then the first StateLink will be automatically removed. (and it will be
>> updated atomically: any thread will see either the old link, or the new
>> link, and will never see both, and will never see neither.)
>>
>> I did all of the Hanson Robotics code using StateLink.  It was used to
>> represent anything that modelled the external world, and was changing in
>> time -- who the robot was looking at, what the robot was doing (smiling,
>> frowning.,..), affective state (content, anxious, ...), the current topic
>> of conversation, the previous sentence...  You can use it to hold not only
>> the state of the arm, but also the arrangement of the blocks on the table.
>>
>> -- AtomSpace push and pop. The idea here is to create temporary "scratch"
>> atomspaces, write stuff into them, and then throw them away by popping them
>> off the stack. Ideal for recursive algorithms.  For example:
>>
>> ; Initial atomspace contains four blocks on table and empty robot arm.
>> (cog-push-atomspace)
>> ; Run rule to pick up block. Atomspace now has three blocks on table, and
>> arm holding block A.
>> (cog-push-atomspace)
>> ; Run rule to place block A on top of block B. robot arm is now empty
>> again.
>> ; print "success!" to output
>> (cog-pop-atomspace)
>> ; Popping the atomspace is like going backwards in time...
>> (cog-pop-atomspace)
>> ; After the second pop, we are now back to the initial state, of
>> unstacked blocks and empty arm.
>>
>> The above works fine, in general. However:
>> 1) StateLink may be buggy with push-pop.  No one has ever used them
>> together!!
>> 2) The URE (and PLN) does NOT use push/pop during
>> rule-application/reasoning (?? Not sure.. right, Nil??) Thus, if you apply
>> some rule, it changes the contents of the atomspace, and there is no easy
>> way to go "backwards in time" and pretend the rule was never applied. This
>> is particularly important during reasoning, when rules may have
>> side-effects that affect the state !!! Without push-pop, there is no way to
>> undo the state change!
>>
>> I guess that's all.  A few words about the general idea.
>>
>> ** Each atomspace, after a push or pop, is formally called a "Kripke
>> frame" -- it is a "what if" model of the "current universe".  The concept
>> of Kripke frames allows "modal logic" to be used in understanding things.
>> For example, "what if I stack block B on top of block A?"  -- given that
>> hypothetical universe, you can then explore further: "suppose I put block C
>> on block B, then what?"
>>
>> ** Besides push and pop, you can navigate to different atomspaces, and
>> so, in general, there will be a lattice of possible worlds, and you can
>> take a birds-eye view of all of those worlds (and perform reasoning on
>> them).
>>
>> That's the general idea. There may be bugs and usability issues.
>> a) StateLink might work badly with the push-pop
>> b) Truth values may work badly with push-pop. I think we fixed this once,
>> but there might be bugs.
>> c) URE and PLN mostly don't take advantage of push-pop, and thus, if you
>> have a rule that has side-effects, they are not isolated. That is, the URE
>> is not "hygenic". (for the schemers reading this: the URE is like a macro
>> system...)
>>
>> I'll take a look at a) and b) shortly.
>>
>> I am sorry you are running out of time. I'm not sure how to best spend
>> the time remaining. Probably the best thing to do is what Adrian suggested:
>> make sure that you can apply rules, one at a time, by hand, and that you
>> get the expected results.  At least, that way, you get a collection of
>> rules that "work", and you'd be missing a chainer for them.  Automatically
>> chaining them would then be some other, future step.
>>
>> --linas
>>
>>
>>
>>
>> On Fri, Aug 27, 2021 at 4:57 AM Michele Thiella <[email protected]>
>> wrote:
>>
>>> Hello everyone and thanks for your time,
>>> unfortunately i almost out of time due to graduation deadlines...
>>>
>>> As Nil reminds me, atomspace is used as immutable data storage. I always
>>> knew this but I realized late what it means on a practical level...
>>> I tried to use it dynamically, adding and removing atoms during the
>>> reasoning. I think this is the biggest mistake that didn't allow me to get
>>> to a solution with backwards chaining.
>>>
>>> Responding to Nil's proposals:
>>>
>>> 1. I think temporal reasoning is the most correct way .. and it would
>>> come close to the ROCCA model (the one you presented in a meeting some time
>>> ago), if I'm not mistaken.
>>> 2. I tried some solutions describing each state explicitly but (now I
>>> don't remember well) the problem was the lack of generality of the rules
>>> (probably my lack of knowledge didn't allow me to generalize them properly)
>>> ...
>>> As I write this, new solutions are coming to my mind and I would really
>>> like to have the time to try them all.
>>> Anyway, I don't know why, I never considered inferring action rather
>>> than cubes... although, it's logically obvious!
>>>
>>> In conclusion, a few days ago I talked to Adrian Borucki (I hope I'm not
>>> wrong) and I tried a step-by-step approach... so, I run one rule at a time
>>> and the effects are applied in the atomspace.
>>> Ok.. it works, of course.
>>> I wrote breadth-first tree expansion algorithm, which starts from the
>>> initial arrangement and tries all available actions, for each result it
>>> creates a new node of the tree (and apply the effect of that action in its
>>> atomspace) and repeats until reaching the goal.
>>>
>>> I don't think it's the correct way to use the atomspace but with the
>>> rules I had written, my previous knowledge and lack of time, I couldn't do
>>> better.
>>>
>>> Unfortunately, I rely on the university's private Ros codes for the
>>> first part of the project, which I cannot disclose.
>>> Within the next 2 weeks (or a little more) I should be able to replace
>>> them with a fake code and therefore makes everything open source
>>>
>>> For now I think to keep this way... but after graduation, maybe I will
>>> implement one of the correct approaches!
>>> It has become a personal challenge!
>>>
>>> Thanks again for your availability!
>>>
>>> Michele
>>> Il giorno giovedì 26 agosto 2021 alle 18:40:37 UTC+2 linas ha scritto:
>>>
>>>> I've been travelling, and will try to read and write a response "real
>>>> soon now" (next few days).
>>>>
>>>> --linas
>>>>
>>>> On Sat, Aug 14, 2021 at 9:36 AM Michele Thiella <[email protected]>
>>>> wrote:
>>>>
>>>>> Hello everyone,
>>>>> I will try to explain in a simple way:
>>>>>
>>>>> 1) my problem and my goal
>>>>> 2) the possible solutions
>>>>> 3) errors/shortcomings found and extra questions encountered along the
>>>>> way
>>>>>
>>>>>
>>>>> *1) The Problem:*
>>>>>
>>>>> Let's start from scratch. My problem is based on the classic problem
>>>>> called "blocksworld problem". That is:
>>>>>
>>>>> - there is a robot manipulator that has 4 actions available:
>>>>> pickup, putdown, stack, unstack.
>>>>>
>>>>> - there are blocks on a table
>>>>>
>>>>> - there is a goal to be achieved
>>>>>
>>>>> *The Goal: *
>>>>> I am trying to solve any possible arrangement of the blocks. So my
>>>>> work aims to take as input a final arrangement of the blocks and
>>>>> through backward inference, obtain the derivation tree to reach that
>>>>> arrangement, through the 4 actions mentioned above.
>>>>> (I'll explain better later)
>>>>>
>>>>>
>>>>> *The construction of the problem:*
>>>>>
>>>>> - each block can be "clear", ie. the robot can take it
>>>>> (it is not clear to me if the vice versa "not-clear" is also necessary)
>>>>>
>>>>> - the robot hand may be "busy": so it is holding a block. Or "free":
>>>>> it has nothing in its hand
>>>>>
>>>>> - the 4 actions:
>>>>>
>>>>> 1) pickup:
>>>>>      - preconditions: "clear" block, "on-table" block and "free"
>>>>> (robot) hand
>>>>>      - effects: "not-clear" block, "in-hand" block and "busy" hand
>>>>>
>>>>> 2) putdown:
>>>>>      - preconditions: "not-clear" block, "in-hand" block and "busy"
>>>>> hand
>>>>>      - effects: "clear" block, "on-table" block and "free" hand
>>>>>
>>>>> 3) stack:
>>>>>      - preconditions: block1 "in-hand", block2 "clear" and "busy" hand
>>>>>      - effects: block2 "not-clear", block1 "on" block2, block1 "clear"
>>>>> and hand "free"
>>>>>
>>>>> 4) unstack:
>>>>>      - preconditions: block2 "not-clear", block1 "on" block2, block1
>>>>> "clear" and hand "free"
>>>>>      - effects: block1 "in-hand", block2 "clear" and "busy" hand
>>>>>
>>>>> Basically the 4 actions mirror physics.
>>>>> Eg. If I want to take a block from the table, the block must be free
>>>>> ("clear") and my hand must be free.
>>>>> If block A is "on" block B then I can "unstack" block A and then make
>>>>> block B "clear" and having block A in hand.
>>>>>
>>>>> Obviously the pickup action is the opposite of putdown and are used to
>>>>> take/place a block from/on the table.
>>>>> The stack action is the opposite of unstack and are used to put/take a
>>>>> block on/from another block.
>>>>>
>>>>> I hope the introduction to the problem is complete enough.
>>>>>
>>>>> *2) Implementation:* (note that I'm looking for an Atomese-pure
>>>>> implementation)
>>>>>
>>>>> - Initial Set in the atomspace:
>>>>> An external algorithm detects all the blocks present on the table
>>>>> (for now the initial arrangement of the blocks does not have any
>>>>> blocks on top of another, as the detection of the blocks is done through
>>>>> Apriltag
>>>>> and therefore I would not be able to find the blocks placed under
>>>>> others.
>>>>> If I have time I will solve this problem using PointCloud.
>>>>> This is to say that my initial block arrangement can be any.
>>>>> Eg. 4 blocks:
>>>>>  - A on B on C, D on table
>>>>>  - A on D, B on C
>>>>>  - A, B, C, D on table
>>>>>  - and so on ...
>>>>> )
>>>>>
>>>>> So my atomspace will be about:
>>>>>
>>>>> (SetLink
>>>>>     ; block1
>>>>>     (InheritanceLink (stv 1 1)
>>>>>         (ConceptNode "block1")
>>>>>         (ConceptNode "object"))
>>>>>
>>>>>     (EvaluationLink (stv 1 1)
>>>>>         (PredicateNode "clear")
>>>>>         (ConceptNode "block1"))
>>>>>
>>>>>     ; block2
>>>>>     ; ....
>>>>>
>>>>>     ; differentiate the various blocks
>>>>>     (NotLink (EqualLink (ConceptNode "block1") (ConceptNode "block2")))
>>>>> )
>>>>>
>>>>> - Goal Implementation:
>>>>> it completely depends on how the model is formulated.
>>>>> If you look for a state resolution (finite state machine type) the
>>>>> goal will be formulated as one of them.
>>>>> Alternative: in the end, each block will always be on top of something
>>>>> (table or other block) so a possible goal formulation would be like:
>>>>>
>>>>> (define (compute)
>>>>>    (define goal-state
>>>>>       (AndLink
>>>>>          (ListLink
>>>>>             (VariableNode "$ A")
>>>>>             (VariableNode "$ B")
>>>>>          )
>>>>>          (ListLink
>>>>>             (VariableNode "$ B")
>>>>>             (VariableNode "$ C")
>>>>>          )
>>>>>          (NotLink (EqualLink (VariableNode "$ A") (VariableNode "$
>>>>> B")))
>>>>>          (NotLink (EqualLink (VariableNode "$ A") (VariableNode "$
>>>>> C")))
>>>>>          (NotLink (EqualLink (VariableNode "$ B") (VariableNode "$
>>>>> C")))
>>>>>       )
>>>>>    )
>>>>>    (define vardecl
>>>>>       (VariableList
>>>>>          (TypedVariableLink
>>>>>             (VariableNode "$ A")
>>>>>             (TypeNode "ConceptNode"))
>>>>>          (TypedVariableLink
>>>>>             (VariableNode "$ B")
>>>>>             (TypeNode "ConceptNode"))
>>>>>          (TypedVariableLink
>>>>>             (VariableNode "$ C")
>>>>>             (TypeNode "ConceptNode"))
>>>>>          (TypedVariableLink
>>>>>             (VariableNode "$ D")
>>>>>             (TypeNode "ConceptNode"))
>>>>>       )
>>>>>    )
>>>>>    (cog-bc rbs goal-state #: vardecl vardecl)
>>>>> )
>>>>>
>>>>> - Rules for inference:
>>>>> Same considerations made for the formulation of the goal.
>>>>> Let's start with the rules corresponding to the 4 robot actions and
>>>>> leave out extra rules.
>>>>> If we rely on the definition above, then for example the stack rule
>>>>> would be something like:
>>>>>
>>>>> (define stack
>>>>>    (BindLink
>>>>>       (VariableList
>>>>>          (TypedVariableLink (VariableNode "?ob") (TypeNode
>>>>> "ConceptNode"))
>>>>>          (TypedVariableLink (VariableNode "?underob") (TypeNode
>>>>> "ConceptNode"))
>>>>>       ) ; parameters
>>>>>       (PresentLink
>>>>>          (NotLink
>>>>>             (EqualLink (VariableNode "?ob") (VariableNode "?underob")))
>>>>>          (InheritanceLink
>>>>>             (VariableNode "?ob")
>>>>>             (ConceptNode "object"))
>>>>>          (InheritanceLink
>>>>>             (VariableNode "?underob")
>>>>>             (ConceptNode "object"))
>>>>>          (AndLink
>>>>>             (EvaluationLink
>>>>>                (PredicateNode "in-hand")
>>>>>                (VariableNode "?ob"))
>>>>>             (EvaluationLink
>>>>>                (PredicateNode "clear")
>>>>>                (VariableNode "?underob"))
>>>>>          )
>>>>>       )
>>>>>       (ExecutionOutputLink
>>>>>          (GroundedSchemaNode "scm: stack-action")
>>>>>          (ListLink
>>>>>             ; effect:              this represent ?ob "on" ?underob
>>>>>             (ListLink
>>>>>                (VariableNode "?ob")
>>>>>                (VariableNode "?underob")
>>>>>             )
>>>>>             ; precondition
>>>>>             (AndLink
>>>>>                (EvaluationLink
>>>>>                   (PredicateNode "in-hand")
>>>>>                   (VariableNode "?ob"))
>>>>>                (EvaluationLink
>>>>>                   (PredicateNode "clear")
>>>>>                   (VariableNode "?underob"))
>>>>>             )
>>>>>          )
>>>>>       )
>>>>>    )
>>>>> )
>>>>>
>>>>>
>>>>> *3)* Before talking about the problems that this writing (and the
>>>>> state-based alternative) has, I would like to talk about backward 
>>>>> inference.
>>>>>
>>>>> Probably the implementation and functioning of URE is my biggest
>>>>> shortcoming
>>>>> and also the reason why I don't find the right way to formulate and
>>>>> solve this problem. Some questions:
>>>>>
>>>>> 3.1) I've always seen backward inference work via BindLink and
>>>>> VariableNode. I have no idea if there is an alternative/better way to do 
>>>>> it.
>>>>>
>>>>> 3.2) As Linas mentioned, BindLink requires PresentLink and this is one
>>>>> of the biggest problems.
>>>>> By backward inference the rules are called and combine into a large
>>>>> BindLink and the same is true for the PresentLink.
>>>>> In the end, you get a large PresentLink made up of all the
>>>>> PresentLinks of the called rules.
>>>>> This means that for example I cannot use atoms like
>>>>>
>>>>> ; atom [0]
>>>>> (EvaluationLink
>>>>>                (PredicateNode "clear")
>>>>>                (VariableNode "? Ob"))
>>>>> ; atom [1]
>>>>> (EvaluationLink
>>>>>                (PredicateNode "not-clear")
>>>>>                (VariableNode "? Ob"))
>>>>>
>>>>> because it doesn't make sense that the same block is both "clear" and
>>>>> "not-clear".
>>>>>
>>>>> ----------------------
>>>>> PS. this leads to another question: is what I am saying correct? I'll
>>>>> explain:
>>>>> Suppose I have 2 rules. One has the atom [0] in the PresentLink and
>>>>> the other has the atom [1].
>>>>> Suppose the rules are called in succession from backward inference.
>>>>> When is PresentLink evaluated? From what I've seen:
>>>>>
>>>>> 1) the two rules compose the new BindLink, containing the PresentLink
>>>>> of both (which I think is the "Expanded forward chainer strategy")
>>>>> 2) The BindLink is evaluated and then the solutions are found or not
>>>>> (which I think is the "Selected and-BIT for fulfillment")
>>>>>
>>>>> Then, only at the end, the PresentLink is evaluated, this implies that
>>>>> both atoms [0] and [1] must be present together in the atomspace.
>>>>>
>>>>> This is incorrect: "The PresentLink of each rule is evaluated when
>>>>> that rule is called." Right?
>>>>> ----------------------
>>>>>
>>>>> That said, it wouldn't seem like a problem. Instead it is,
>>>>> because it means that once the rule writes a new atom into the
>>>>> atomspace
>>>>> then that atom will always be present and therefore the rule that uses
>>>>> that atom as a precondition can be called whenever it wants.
>>>>> Consequently , in example:
>>>>>
>>>>> - blocks A, B, C
>>>>> - initial arrangement: A "on" B, C on the table
>>>>> - goal: Variable ?ob "on" Variable ?underob
>>>>>
>>>>> Consequently, for example, the use of certain atoms is no longer good
>>>>> for trying to follow the physics of actions
>>>>> (eg hand- "busy" and hand- "free": I can only take an object if my
>>>>> hand is free).
>>>>> The two atoms will always appear in the PresentLink and therefore,
>>>>> after doing a "pickup" and a "putdown",
>>>>> I can do two "pickups" in a row without worrying about having to put
>>>>> the object down first.
>>>>> So, you don't understand anything.
>>>>> But essentially the presence of certain atoms to limit the solutions
>>>>> to only physically correct sequences of actions does not work (or at least
>>>>> I have not been able to find a logic that fits).
>>>>>
>>>>>
>>>>> 3.3) Mirror problem with unstack rule:
>>>>>
>>>>> First let's take a step back:
>>>>>
>>>>> - blocks A, B, C
>>>>> - initial arrangement: A, B, C on the table
>>>>> - goal:
>>>>>             (AndLink
>>>>>                (ListLink
>>>>>                   (VariableNode "?ob")
>>>>>                   (VariableNode "?underob")
>>>>>                )
>>>>>                (NotLink (EqualLink (VariableNode "?ob") (VariableNode
>>>>> "?underob")))
>>>>>             )
>>>>>
>>>>>
>>>>> Backward inference could call the following rules in order:
>>>>> (conjunction joins two Links in a AndLink)
>>>>>
>>>>> (goal) <- conjunction <- stack <- conjunction <- pickup <- (init-set)
>>>>>
>>>>>
>>>>>
>>>>> (EvaluationLink (PredicateNode "clear")(VariableNode "?ob"))
>>>>>
>>>>> ----------------------------------------pickup-action----------------------------------------
>>>>> (EvaluationLink (PredicateNode "in-hand") (VariableNode "?ob"))
>>>>>                                          (EvaluationLink (PredicateNode
>>>>> "clear")(VariableNode "?underob"))
>>>>>
>>>>> ==========================================================conjunction============================================================
>>>>>
>>>>>                            (AndLink
>>>>>
>>>>>                                 (EvaluationLink
>>>>>
>>>>>                                    (PredicateNode "in-hand")
>>>>>
>>>>>                                    (VariableNode "?ob"))
>>>>>
>>>>>                                 (EvaluationLink
>>>>>
>>>>>                                    (PredicateNode "clear")
>>>>>
>>>>>                                    (VariableNode "?underob"))
>>>>>
>>>>>                            )
>>>>> -------------------------------------------------------------------------------------------------------
>>>>> stack-action ----------------------------------
>>>>>
>>>>>                            (ListLink
>>>>>
>>>>>                               (VariableNode "?ob")
>>>>>
>>>>>
>>>>>                               (VariableNode "?underob")
>>>>>                                            (NotLink (EqualLink
>>>>> (VariableNode "?ob") (VariableNode "?underob")))
>>>>>
>>>>> ==========================================================conjunction=========================================================================================
>>>>>
>>>>>                                        (AndLink
>>>>>
>>>>>                                           (ListLink
>>>>>
>>>>>                                              (VariableNode "?ob")
>>>>>
>>>>>                                              (VariableNode "?underob")
>>>>>
>>>>>                                           )
>>>>>
>>>>>                                           (NotLink (EqualLink 
>>>>> (VariableNode
>>>>> "?ob") (VariableNode "?underob")))
>>>>>
>>>>>                                        )
>>>>>
>>>>>
>>>>> and returns as a solution all the combinations of the 3 blocks one
>>>>> above the other two by two.
>>>>> This is great, but analyzing the rules, then "unstack" would be of the
>>>>> form:
>>>>>
>>>>>
>>>>>
>>>>>                            (ListLink
>>>>>
>>>>>                               (VariableNode "?ob")
>>>>>
>>>>>                               (VariableNode "?underob")
>>>>> -----------------------------------------------------------------------------------------------------------------
>>>>> unstack-action
>>>>> -----------------------------------------------------------------------------------------------------------------
>>>>>
>>>>>                            (AndLink
>>>>>
>>>>>                                 (EvaluationLink
>>>>>
>>>>>                                    (PredicateNode "in-hand")
>>>>>
>>>>>                                    (VariableNode "?ob"))
>>>>>
>>>>>                                 (EvaluationLink
>>>>>
>>>>>                                    (PredicateNode "clear")
>>>>>
>>>>>                                    (VariableNode "?underob"))
>>>>>
>>>>>                            )
>>>>>
>>>>>
>>>>> and now the trouble begins, because, as for the conjunction rule used
>>>>> for stack, then I need a disjunction for unstack rule,
>>>>>
>>>>>
>>>>>                            (AndLink
>>>>>
>>>>>                                 (EvaluationLink
>>>>>
>>>>>                                    (PredicateNode "in-hand")
>>>>>
>>>>>                                    (VariableNode "?ob"))
>>>>>
>>>>>                                 (EvaluationLink
>>>>>
>>>>>                                    (PredicateNode "clear")
>>>>>
>>>>>                                    (VariableNode "?underob"))
>>>>>
>>>>>                            )
>>>>>
>>>>> ==========================================================disjunction============================================================
>>>>> (EvaluationLink (PredicateNode "in-hand") (VariableNode "?ob"))
>>>>>                                          (EvaluationLink (PredicateNode
>>>>> "clear")(VariableNode "?underob"))
>>>>>
>>>>>
>>>>> Which from what I know is not possible to have because there is always
>>>>> a single atom as an effect and a single atom as a precondition.
>>>>> But there should be something like the composition rule:
>>>>>
>>>>> Γ′⊢ψ                      Γ, ψ, Γ ”⊢ ∇
>>>>> --------------------------------------------------
>>>>>            Γ, Γ ′, Γ′′⊢ ∇
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> 3.4) Finally, the last and I think the most important question: let's
>>>>> try to work by states.
>>>>> Well, I have tried many ways and I have not succeeded in any.
>>>>> Basically I found some shortcomings rather than logical errors.
>>>>>
>>>>> As has been said, the number of states for this problem is large to
>>>>> have them all in the atomspace (especially if we use a lot of blocks) and 
>>>>> a
>>>>> waste because, based on the goal, 3/4 of the states would be useless.
>>>>>
>>>>> So there are 2 ideas (always in Atomese-pure):
>>>>>
>>>>> 1) Find a rule that takes in (precondition) a state and an action and
>>>>> returns (effect) a new state.
>>>>>
>>>>> 2) Find 4 rules (one for each action) that take in (precondition) a
>>>>> state and return (effect) a new one.
>>>>>
>>>>> So, first of all:
>>>>>
>>>>> - I could not give as a precondition: the last state created.
>>>>> The preconditions and effects of the rules are non-generic atoms. The
>>>>> only possibility I had thought was to have the input state as 
>>>>> VariableNode,
>>>>> so that with fulfillment it would try all the atoms that represented my
>>>>> states.
>>>>> But this is not good because maybe after n actions, instead of taking
>>>>> the n-th state and creating the n + 1-th state, it could take the i-th
>>>>> state and create the n + 1-th state. And of course it is wrong because the
>>>>> i-th state is old and the layout of the blocks has certainly changed. (I
>>>>> hope it's clear enough)
>>>>>
>>>>> This led me to think that StateLink was a good atom for this purpose.
>>>>> - StateLink is unique, so it's fine as a precondition of my rule
>>>>> because it will definitely always represent the current situation of my
>>>>> blocks.
>>>>> Yet when I get a sequence of states as a solution to my inference,
>>>>> then in the PresentLink of my final BindLink all these states are required
>>>>> to be present in the atomspace. And this does not work (always confirming
>>>>> my initial assumption that the presence in the atomspace of the atoms
>>>>> contained in the PresentLink is verified at the time of fulfillment and 
>>>>> not
>>>>> at the call of each rule), because all the StateLinks prior to the last 
>>>>> one
>>>>> no longer exist, for StateLink definition.
>>>>>
>>>>> - I tried associating a Floats Value to the StateLink to represent the
>>>>> state of each block, so for example for each block one bit for "clear" /
>>>>> "not-clear", one bit for "in-hand" / "not-in -hand ", etc ...
>>>>> The idea was to change the status bits of an object as a rule was
>>>>> called on that object.
>>>>>  I guess that's not good because:
>>>>>    - either the bits of the Value are the precondition and the effect
>>>>> of the rule, or the inference does not perceive their change during the
>>>>> calls of the various rules (if for example the flips of the bits occur in
>>>>> the GroundedSchemaNode)
>>>>>    - even if the bits of the Value were the precondition and the
>>>>> effect of the rule, there would still be the PresentLink problem. So once 
>>>>> I
>>>>> have created the "can-pickup" state of block A, it will always be usable
>>>>> because it is inserted in the atomspace, even when A is no longer
>>>>> "pickable".
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> *4) Conclusions:*
>>>>> I think something is missing from the current system to solve this
>>>>> problem (or I need some advice because I can't do it in any way)
>>>>>
>>>>> - The idea is a StateLink which however does not delete its old state
>>>>> but which keeps it in the atomspace. But somehow it can be called
>>>>> generically as a precondition of the rules, and this generic call always
>>>>> refers to the last StateLink created. (I saw that there was an obsolete
>>>>> atom: LatestLink, which maybe took over part of this operation)
>>>>>
>>>>> So the operation would be (call this new atom LatestStateLink):
>>>>>
>>>>> (define choose-action
>>>>>    (BindLink
>>>>>       (VariableList
>>>>>          (TypedVariableLink (VariableNode "?ob") (TypeNode
>>>>> "ConceptNode"))
>>>>>       )
>>>>>       (PresentLink
>>>>>          (InheritanceLink
>>>>>             (VariableNode "?ob")
>>>>>             (ConceptNode "object"))
>>>>>
>>>>>          (LatestStateLink "actual_state"
>>>>>                (ListLink (ConceptNode "?ob") (PredicateNode "state"))
>>>>>                (FloatValue 0 1 0 .....)
>>>>>             )
>>>>>
>>>>>       )
>>>>>       (ExecutionOutputLink
>>>>>          (GroundedSchemaNode "scm: action")
>>>>>          (ListLink
>>>>>             ; effect:
>>>>>             (LatestStateLink "actual_state"
>>>>>                (ListLink (ConceptNode "?ob") (PredicateNode "state"))
>>>>>                (FloatValue 1 1 1 .....)
>>>>>             )
>>>>>             ; precondition
>>>>>             (LatestStateLink "actual_state"
>>>>>                (ListLink (ConceptNode "?ob") (PredicateNode "state"))
>>>>>                (FloatValue 0 1 0 .....)
>>>>>             )
>>>>>          )
>>>>>       )
>>>>>    )
>>>>> )
>>>>>
>>>>> This is very similar to StateLink except for the name given to
>>>>> LatestStateLink. The idea is that the precondition for this rule is to
>>>>> check only the last state relative to the ?ob block and not the previous
>>>>> ones as well. If the last state, which I named "actual_state", has the
>>>>> FloatValue corresponding to the required ones then the rule can be called,
>>>>> otherwise not.
>>>>>
>>>>> When the rule is called the effect is written on the atomspace and
>>>>> then a new LatestStateLink "actual_state" is added and the previous
>>>>> LatestStateLink is left in the atomspace losing the name (so that you have
>>>>> one and only one "actual_state").
>>>>>
>>>>> By doing this, it is possible to write rules in a generic way that
>>>>> respect the physics of actions and function in states.
>>>>> it's just a draft it will probably have other errors but it was one of
>>>>> the ideas that came to me.
>>>>>
>>>>> Unfortunately I haven't even looked at the C ++ implementation part of
>>>>> the Atom and their types. So for "code additions" of this type I think I
>>>>> don't have the time to get by, understand how the C ++ part works and 
>>>>> write
>>>>> the code correctly and completely.
>>>>>
>>>>>
>>>>> This is all I have managed to write. I'm sorry it's so long and I
>>>>> apologize for the many unclear parts and logical and grammatical errors.
>>>>> For those who like it, happy reading!
>>>>>
>>>>> Michele
>>>>>
>>>>> --
>>>>>
>>>> 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 [email protected].
>>>>>
>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/opencog/c9d4af3c-3117-4ea0-8cd2-bb885f108e1cn%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/opencog/c9d4af3c-3117-4ea0-8cd2-bb885f108e1cn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>>
>>>>
>>>> --
>>>> Patrick: Are they laughing at us?
>>>> Sponge Bob: No, Patrick, they are laughing next to us.
>>>>
>>>>
>>>> --
>>> 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 [email protected].
>>>
>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/opencog/01eedcde-0a95-4e4e-b0ad-65ffe98dca45n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/opencog/01eedcde-0a95-4e4e-b0ad-65ffe98dca45n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>
>>
>> --
>> Patrick: Are they laughing at us?
>> Sponge Bob: No, Patrick, they are laughing next to us.
>>
>>
>> --
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/opencog/ee4b8456-828f-4fce-9f78-c196590bf135n%40googlegroups.com
> <https://groups.google.com/d/msgid/opencog/ee4b8456-828f-4fce-9f78-c196590bf135n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>


-- 
Patrick: Are they laughing at us?
Sponge Bob: No, Patrick, they are laughing next to us.

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/opencog/CAHrUA340WND%2B0e5toSxSL3MeaZONrQt32qZXa__2nUeyGE8UfA%40mail.gmail.com.

Reply via email to