Topology / ALM-Compiler

A Java implementation of the ALM language that compiles to the SPARC variant of Answer Set Programming (ASP).
Apache License 2.0
0 stars 1 forks source link

CALM bug? - "singleton" anonymous subsort of elevations in basicmotion_yn #8

Closed zhangyuanlin closed 6 years ago

zhangyuanlin commented 6 years ago

CALM aug 20 version still has this complaint

ErrorID: CND002
Message: Object Constant parameter [elevations at (166:16)] is not a source sort in the 
hierarchy since it has sub-sort [[NO TEXT] at (0,0)]

for the program basicmotion_yn.tp below


%ErrorID: TYP003 (this error is gone) 
%Message: Sort mismatch in expression [box at (204:20)].  Sort [carriables] was expected but a term of sort [[elevations]] occurred.
system description monkeyBanana
    theory basic_motion
        module moving
        sort declarations
            points, things :: universe
            agents :: things
            move :: actions
                attributes
                    actor : agents
                    origin : points
                    dest : points
        function declarations
            statics
                basic
                    symmetric_connectivity : booleans
                    transitive_connectivity : booleans
            fluents
                basic
                    % connnected(P1, P2) - true if P1 and P2 are connected
                    connected : points * points -> booleans
                    % loca_in(T) - the point where thing T is at
                    total loc_in : things -> points
        axioms
            dynamic causal laws
                % move action causes its actor to be at its destination
                occurs(X) causes loc_in(A) = D if
                    instance(X, move),
                    actor(X) = A,
                    dest(X) = D.
            state constraints
                connected(X, X).
                connected(X, Y) if connected(Y, X),symmetric_connectivity.
                -connected(X, Y) if -connected(Y, X),symmetric_connectivity.
                connected(X, Z) if
                    connected(X, Y),connected(Y, Z),transitive_connectivity.
            executability conditions
                % move is not possible if its actor is not at its origin.
                % NEW - what if the origin of actor unknown?
                impossible occurs(X) if
                    instance(X, move),actor(X) = A,loc_in(A) != origin(X).
                    % instance(X, move), loc_in(actor(X)) != origin(X).

                % move is not possible if its actor is at its dest.
                impossible occurs(X) if
                    instance(X, move),actor(X) = A,loc_in(A) = dest(X).
                    % instance(X, move), loc_in(actor(X)) = dest(X).

                % move is not possible if the location of its actor is not
                % connected to its dest.
                impossible occurs(X) if
                    instance(X, move),
                    actor(X) = A,
                    loc_in(A) = O,
                    dest(X) = D,
                    -connected(O, D).

    module carrying_things depends on moving
        sort declarations
            carriables :: things
            % carry <actor, origin, dest, carried_obj>
            %   actor carries carried_obj from origin to dest.
            carry :: move
                attributes
                    carried_object : carriables
            % grasp <grasper, grasped_thing> - rasper grasps grasped_thing
            grasp :: actions
                attributes
                    grasper : agents
                    grasped_thing : things
            % release <releaser, released_thing> -
            %   releaser releases released_thing
            release :: actions
                attributes
                    releaser : agents
                    released_thing : things
        function declarations
            fluents
                basic
                    % holding(A, T) - agent A holds thing T.
                    total holding : agents * things -> booleans
                defined
                    % is_held(T) - thign T is held (by some agent)
                    is_held : things -> booleans
                    % can_reach(A, T) - agent A can reach thing T
                    can_reach : agents * things -> booleans
        axioms
            dynamic causal laws
                % grasp causes its grasper to hold its grasped_thing
                occurs(A) causes holding(X,Y) if
                    instance(A,grasp), grasper(A) = X, grasped_thing(A) = Y.
                % release causes its releaser not to hold its grasped_thing.
                occurs(A) causes -holding(X,Y) if
                    instance(A,release), releaser(A) = X, released_thing(A) = Y.
            state constraints
                % If A holds T, then they have the same location.
                loc_in(T) = P if holding(A,T), loc_in(A) = P.
                loc_in(A) = P if holding(A,T), loc_in(T) = P.
                -holding(X,Y2) if holding(X,Y1), Y1 != Y2.

                % NEW on default values of carry:
                %   its origin is where the agent is
                % general question - principles of where to
                % "set" values of attributes structure or state constraits?
                origin(C) = P if
                    instance(C, carry),
                    loc_in(actor(C)) = P.

            function definitions
                is_held(X) if holding(T,X).
                % Agent M can reach O if they are in the same location
                can_reach(M,O) if loc_in(M) = loc_in(O).
            executability conditions
                % grasp is not possible if its grasper already holds its grasped
                impossible occurs(A) if instance(A,grasp), grasper(A) = X, grasped_thing(A) = Y, holding(X,Y).
                % grasp is not possible if its grasper cannot reach its grasped
                impossible occurs(A) if
                    instance(A,grasp), grasper(A) = X,
                    grasped_thing(A) = Y, -can_reach(X,Y).
                % release is not possible if its releaser does not hold its grasped
                impossible occurs(A) if
                    instance(A,release), releaser(A) = X,
                    released_thing(A) = Y, -holding(X,Y).
                % move is not possible if its actor is held.
                impossible occurs(X) if
                    instance(X,move), actor(X) = A, is_held(A).
                % carry is not possible if its actor does not hold its carried
                impossible occurs(X) if
                    instance(X,carry), actor(X) = A,
                    carried_object(X) = C, -holding(A,C).

    module climbing depends on moving
        sort declarations
            elevations :: things
              attributes
                top: points
            % climb <actor, origin, destination, elevation>
            %    -- actor climbs the elevation (to its top)
            %       (from its origin)
            climb :: move
                attributes
                    elevation : elevations
        % constant declarations
            % top(elevations) : points
        axioms
            state constraints
                % ?? how do we know elevation below is an attribute function??
                % top(E) is the destination of climbing an elevation E
            dest(A) = C if elevation(A) = E, C = top(E).
                % Any thing T cannot locate on top of T
                false if loc_in(T) = top(T).
            executability conditions
                % climb is not possible if its elevation is not in the same
                % location of its actor. 
                impossible occurs(X) if
                    instance(X,climb), actor(X) = A,
                    elevation(X) = O, loc_in(O) != loc_in(A).

    module main depends on carrying_things, climbing
        sort declarations
            floor_points, ceiling_points, movable_points :: points
        constant declarations
            monkey : agents
            box :  elevations
            top(elevations): movable_points
            box, banana : carriables
        function declarations
            statics
                basic
                    % under(P, T) - point P is under thing T
                    under : floor_points * things -> booleans
            axioms
                function definitions
                    % monkey can reach the banana if it is on top of the box
                    % which under the banana
                    can_reach(monkey, banana) if
                        loc_in(box) = P, under(P,banana),loc_in(monkey) = top(box).
                state constraints
                        % The location of the box is connected to the top of the box
                        connected(top(box),P) if
                            loc_in(box) = P, instance(P, floor_points).
                        % top of box is not connected to
                        % any points other than the box's location.
                        -connected(top(box),P) if
                            loc_in(box) != P, instance(P,floor_points).
                        % any two points on floor are connected
                        connected(P1,P2) if
                            instance(P1,floor_points), instance(P2, floor_points).
                        % any ceiling point is not connected to any other point
                        -connected(P1, P2) if
                            instance(P1, ceiling_points),
                            instance(P2,points), P1 != P2.
                executability conditions
                % NEW climb a box is not possible if it is held by some agent
                    impossible occurs(X) if
                      instance(X,climb),
                      elevation(X) = box,
                      is_held(box).

    structure monkey_and_banana
    instances
        under_banana, initial_monkey, initial_box in floor_points
        initial_banana in ceiling_points
        top(X) in movable_points where instance(X, elevations)

        carry(box, P) in carry where instance(P, floor_points)
            actor = monkey
            carried_object = box
            dest = P
        grasp(C) in grasp where instance(C, carriables)
            grasper = monkey
            grasped_thing = C
        release(C) in release where instance(C, carriables)
            releaser = monkey
            released_thing = C

        climb(box) in climb
            actor = monkey
            elevation = box 
            %NEW destination of climb is top of the box
            %dest(monkey) = top(box)

    value of statics
        under(under_banana, banana).
        symmetric_connectivity.
        -transitive_connectivity.

temporal projection
max steps 7
history

    observed(loc_in(box), initial_box, 0).
    observed(loc_in(monkey), initial_monkey, 0).
    happened(grasp(box), 1).
    happened(carry(box, under_banana), 2).
    happened(release(box), 3).
    happened(climb(box), 4).
    happened(grasp(banana), 5).
Topology commented 6 years ago

I will comment out the section that is generating this semantic error. Another nail in the coffin of the idea of "source sorts" being in the DAG sense (leaf in the hierarchy).

Topology commented 6 years ago

There is no more sematic error, however the produced program has no answerset. I am closing this issue since the semantic error is resolved.

test_TM.sparc.txt

zhangyuanlin commented 6 years ago

Ed,

Thanks! I think I understand to some extent your concern.

If you remember, there is a big assumption in the paper (roughly) that every function name is unique. So, we do the same for constants.

In fact, in future, all your concerns can be properly addressed by removing those assumptions (by introducing "local names" and "name spaces.").

A quick conclusion.

For the SPARC program we discussed, I tested and when asking query source(elevations), the answer is no. So, CALM is not correct according to definition of sort-hierarchy. Remember, programer can use source() in their ALM program.

YL

PS I moved these discuss to issue tracker.

From: Edward Wertz edward.o.wertz@gmail.com Sent: Thursday, August 23, 2018 6:44 AM To: Zhang, Y; Chandrasekaran, Anuradha Subject: Re: Fw: [Topology/ALM-Compiler] CALM bug? - "singleton" anonymous subsort of elevations in basicmotion_yn (#8)

Since we have no way of marking a sort as closed, every user defined sort can be extended in the future. Any constants declared would become instances of non-source sorts ( dag sense of source).

I do not think my translation is solid because I try to erase the inferred singletons in the final program, but do not do a complete job of it. Since we invent the name of the created singleton, it looks ugly and may be unexpected by the programmer. But I think the correct solution is to leave them in and have the constants have is_a( const, singleton-sort) be true.

For type checking, the singletons are used as valid types.

Ultimately the final solver has no concept of sort or type, and treats all entities with the same syntax as the same entity. These types of issues can only be caught by type checking if we want to enforce them.

Part of the problem is that ALM has no facility for namespace. And this is where the java sense of package is not just a set of classes. The name of the package is also the namespace of the classes it contains. If two different packages have the same name of a class, they are not the same class. If another class uses both classes of the same name, they must always use the fully qualified name to differentiate usage and avoid ambiguity.

The reason I am always going to a theoretic discussion on this bug report is because I feel like our formal understanding here is weak.

In Java, if a third class imports two other classes, all instances keep their state separate from each other because in reality the package name of the class and the class name itself act as a namespace on the internal state, keeping it separate.

An ALM module import/dependency says "take your insides and make them my insides". Which is fine for completely orthogonal modules that do not share named entities. But since we have no concept of namespaces, flattening modules which overlap in named entities may have significant and subtle unintended consequences, such as treating what were different semantic entities as the same semantic entity from the ambiguity of using the same syntactic representation in separate modules.

This is why I brought up the example of not wanting to treat these two constant declarations as the same.

John : horse, person

And

John :horse John :person

The first gets an inferred singleton or "anonymous" subsort that acts as the source of the instance.

The second may be a result of two different module imports contributing the statements separately.

So the original question in your bug report is do these anonymous singletons we introduced matter? Are they evidence of non-source (dag sense) of the parent sort? My answer is yes. We added them to the hierarchy for a reason, which is to carry the work of semantic unification of two constants of two different sorts. John being a horse and a person in the same statement makes john different from every other person and every other horse. He is a different fundamental kind of entity and we can create state constraints which target John specifically apart from other persons. In that sense, John is not in the same equivalence class as other persons or horses.

Regardless.of what my compiler does now, what it should do is a big open question. If we automatically unify all entities with the same syntax as the same semantic entity during module flattening, then a programmer must fully understand all modules and the interaction between all modules when flattened. This severely limits the modularity and reusability of the modules. In Java, I don't have to worry about colliding with another objects private state since they are kept separate by namespace. I can write java programs which have 50 chains deep of nested imports and dependencies, all hidden from my view and of no concern to me.

But with module flattening... now I have to know the full stack of dependencies and interactions on flattening. Fine for small problems. But if ALM programming takes off, name collision is going to become a serious issue.

Edward

On Aug 23, 2018 12:25 AM, "Zhang, Y" Y.Zhang@ttu.edu wrote: thanks. I think that is not what I want to know about my question. Maybe my question is not clear.

1) Is it true that some source sort has hidden subsort? (we have [[no text]] is a subsort of elevations, roughly).

2) If a source sort A has a hidden subsort, is A a source sort? (My understanding is yes. But from the bug report, it seems that CALM treats elevations as a non-source sort. If you think that is correct, that is fine. I just want to make sure you are aware of it.)

YL