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/CAHrUA34Sfetwf93O33H6Yrd3%3DtaMwyymcxW1rkhEZU5sNTmnqQ%40mail.gmail.com.

Reply via email to