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.

Reply via email to