Action Languages and Elaboration Tolerance, Part 2
Date: Wed, 19 Sep 2001
From: Vladimir Lifschitz
To: Michael Gelfond
After reading your last message, I understand your approach a lot better.
I'll try to describe, first of all, my current understanding of your
method, and please tell me if anything here is incorrect.
=============================================================================
I. If we want to formalize the original form of MCP and don't care about
elaboration tolerance, this can be done in action language B. In such a
formalization, the requirement that missionaries be not outnumbered by
cannibals is expressed by a static law that corresponds to the logic
programming constraint
:- time(T), num(N), num(N1), gt(N,N1), gt(N1,0),
h(located(cannibal,N),T),
h(located(missionary,N1),T).
II. If, however, we want to be better prepared to formalize elaborations
of MCP, then we should use a more expressive action language B+. Besides
inertial fluents available in B, this extension has also symbols for
non-inertial fluents. Besides static and dynamic laws, in B+ we can also
write propositions of a new kind -- "defaults". This feature allow us
to improve the formalization of the requirement mentioned above. The new
formalization uses the non-inertial fluent harmless, which is essentially
an abnormality predicate. It includes a default expressing that this
fluent is normally false. The requirement that missionaries be not
outnumbered by cannibals is expressed now by a static law that corresponds
to the constraint with an additional atom in the body:
:- time(T), num(N), num(N1), gt(N,N1), gt(N1,0),
h(located(cannibal,N),T),
h(located(missionary,N1),T),
nh(harmless,T).
This modification leaves the transition diagram essentially unchanged -- it
is still a formalization of the original MCP. But now we are ready for the
next step.
III. To disable the restriction on the number of missionaries and cannibals
in the case when cannibals have been converted, we simply add a static law
that corresponds to the rule
h(harmless,T) :- time(T),
h(converted,T).
=============================================================================
Now here is where I see a problem with this method. The claim that the
modification described in Part II leaves the transition diagram essentially
unchanged seems to be incorrect. According to the semantics of B+, states
are defined in the same way as in B: a state is a consistent and complete
collection of fluent literals which is closed under the static rules.
Consequently, nothing prevents fluent harmless from being true. Replacing
formalization I by formalization II adds many new states to the transition
diagram; the states in which harmless is false correspond to the states
in the original formalization, and the states in which harmless is true are
new states, which are rather peculiar. These strange states cannot result
from executing any action. If we try to execute the wait action in such a
state, we may find that it is nonexecutable; if it is executable, the result
will be a different state -- harmless will change its value from true to
false.
Is this correct?
=========
Date: Sun, 23 Sep 2001
From: Michael Gelfond
To: Vladimir Lifschitz
In the beginning your statements are marked with >>>.
>>> Now here is where I see a problem with this method.
>>> The claim that the modification described in Part II leaves the
>>> transition diagram essentially unchanged seems to be incorrect.
I do not think I made such a claim. I maybe missing something though.
>>> According to the semantics of B+, states
>>> are defined in the same way as in B: a state is a consistent and complete
>>> collection of fluent literals which is closed under the static rules.
and defaults, of course, which are just a special form of static rules.
>>> Consequently, nothing prevents fluent harmless from being true. Replacing
>>> formalization I by formalization II adds many new states to the transition
>>> diagram; the states in which harmless is false correspond to the states
>>> in the original formalization, and the states in which harmless is true are
>>> new states,
Right.
>>> which are rather peculiar. These strange states cannot result
>>> from executing any action.
>>> If we try to execute the wait action in such a
>>> state, we may find that it is nonexecutable;
Why?
>>> if it is executable, the result
>>> will be a different state -- harmless will change its value from true to
>>> false. Is this correct?
Yes
A few comments: I understand that you may find states
containing harmless to be strange.
I am not so sure myself but notice that we can easily get rid of such states.
That is what I was trying to suggest in the beginning of the discussion:
Here is a quote from me:
>>>>>> Vladimir, as far as I understand you want
>>>>>> to expand B by a default statements like
>>>>>> 3. Normally F if G (p.s. I named it d)
>>>>>> Is that right?
>>>>>> If so then I think this can be done simply by expanding
>>>>>> B by statements of the form (3) which should be given names
>>>>>> and by statements
>>>>>> 4. exception(Q,d)
>>>>>> which says that Q is an exception to default d.
>>>>>> So let d be of the type (3). Then its meaning is
>>>>>> 'any state containing G and not containing
>>>>>> exceptions to d contains F'.
p.s.
(Exceptions here are viewed as 'strong' exceptions, i.e. any state
containing exception Q also contains ~F. )
I am not sure I made it completely clear though. I was suggesting
to consider a new definition of the state. More formally:
We say that any collection, S, of literals
is 'CLOSED under default d' if S contains F whenever S contains
G and does not contain any Q such that exception(Q,d) is in AD.
This is different from a standard notion of closure I used before.
A STATE of AD is a consistent and complete set of literals
closed under 'old' static laws and the defaults of AD.
Now we could consider a language, say B++,
obtained from B by adding non-inertial fluents
and statements of the type (3) and (4) where F is non-inertial.
The semantics is again defined by translation to logic programming.
(3) and (4) are translated into
h(F,T) <-- h(G,T), not ab(d,T).
ab(d,T) <-- exception(Q,d),
h(Q,T).
~h(F,T) <-- exception(Q,d),
h(Q,T).
The rest is as in B+.
To continue my quote:
>>>> So if your action description does not contain 4 then
>>>> (G,Q,~F) is not a state.
>>>> If 4 is added then it does become a state.
Note that if we are given a domain description D consisting of
action description AD containing (3) without exceptions
and a collection of observations
h(G,0).
~h(F,0).
then D is inconsistent in B++.
If D is viewed as a domain description of B+ then it is consistent.
The difference between the semantics of B+ and B++
depends on their understanding of defaults and their exceptions.
The approach of B+ assumed that default (3) can be defeated by ~F.
The approach of B++ assumed that every default is supplied
with a complete list of exceptions and that the default can be
defeated only by one of them.
You said before:
>>>>>My "normally" represents a very strong default. To override it, we have to
>>>>>explicitly mention the abnormality predicate.
which probably corresponds to the view of B++.
I am not sure which is better but I think now
that B++ should satisfy your original requirements.
Am I right?
If so it may be interesting to see what is its relationship with your new C.
=========
Date: Sun, 23 Sep 2001
From: Vladimir Lifschitz
To: Michael Gelfond
It seems to me now that my attempt to summarize your position was
inadequate. Part II of my summary doesn't reflect your views correctly,
right? Your view is that the action language needed to handle this
elaboration by adding rules is language B++, not B+, correct?
> > Now here is where I see a problem with this method.
> > The claim that the modification described in Part II leaves the
> > transition diagram essentially unchanged seems to be incorrect.
>
> I do not think I made such a claim. I maybe missing something though.
No, you didn't. I referred to Part II of my attempt to summarize your
position. That summary, as I now see, was inadequate.
> > According to the semantics of B+, states
> > are defined in the same way as in B: a state is a consistent and complete
> > collection of fluent literals which is closed under the static rules.
>
> and defaults, of course, which are just a special form of static rules.
This is something that I am not clear about. First, your description of B+
gave me the impression that defaults in B+ are propositions of a new kind,
not a special case of static or dynamic laws. In the description of B+
you wrote:
> Transition diagrams (over this signature) are defined by
> static and dynamic causal laws as in B, impossibility
> conditions, and defaults, i.e. statement of the form
>
> 'Normally a NON-inertial fluent F has the value true (false)'
Second, what do we mean by saying that a set of fluent literals is closed
under a default? Recall that we are talking now about B+, not about B++.
> > These strange states cannot result from executing any action.
> > If we try to execute the wait action in such a
> > state, we may find that it is nonexecutable;
>
> Why?
Maybe I am wrong, but here is what I was thinking. Consider a state in
which harmless is true, and missionaries are outnumbered on one bank.
According to the semantics of B+, will the wait action be executable in
this state?
> I understand that you may find states
> containing harmless to be strange.
> I am not so sure myself but notice that we can easily get rid of
> such states.
Easily, but not until we move from B+ to B++, right? What bothers me is
not so much that we get these states, but that we apparently cannot
get rid of them without making changes in the definition of the action
language.
> I think now
> that B++ should satisfy your original requirements.
I think so too. In the message that started this discussion, I wrote:
So here is the source of many of our difficulties: the set of states in the
transition diagram denoted by a set of propositions depends on that set
monotonically. In a sufficiently expressive action language, this should
not be the case.
It seems to me that you overcome this difficulty by moving from B and B+
to B++.
> If so it may be interesting to see what is its relationship with your new C.
As a step in this direction, consider an application of our "new C" -- C
with statically determined fluents -- to a problem that is not related to
elaboration tolerance. The problem is to give a description of the blocks
world such that the set of states of the corresponding transition diagram
doesn't include any physically impossible states, in which some blocks
form circular configurations in space:
on(b1,b2), on(b2,b3), on(b3,b1).
In our new C, we can achieve this goal by defining the transitive closure
("above") of the predicate on; then we introduce the constraint requiring
that every block be located above the table. But this will only work if
the transitive closure is treated as a statically defined fluent; we could
not do this in the old C.
Can you give such a "perfect" description of the blocks world in B++ ?
=======
Date: Tue, 2 Oct 2001
From: Michael Gelfond
To: Vladimir Lifschitz
M. > and defaults, of course, which are just a special form of static rules.
V. > This is something that I am not clear about.
You are right. This is complete nonsense. I was probably thinking about B++.
You are also right saying that 'wait' maybe non-executable in B+. And I agree
that this is unintuitive.
M. > I think now that B++ should satisfy your original requirements.
V. > I think so too. In the message that started this discussion, I wrote:
So here is the source of many of our difficulties: the set of states in the
transition diagram denoted by a set of propositions depends on that set
monotonically. In a sufficiently expressive action language, this should
not be the case.
It seems to me that you overcome this difficulty by moving from B and B+
to B++.
Good, so we seem to be in agreement.
M. > If so it may be interesting to see what is its relationship with
> your new C.
V. > As a step in this direction, consider an application of our "new C"
> -- C with statically determined fluents -- to a problem that is not
> related to elaboration tolerance. The problem is to give a
> description of the blocks world such that the set of states of the
> corresponding transition diagram doesn't include any physically
> impossible states, in which some blocks form circular configurations
> in space:
>
> on(b1,b2), on(b2,b3), on(b3,b1).
>
> In our new C, we can achieve this goal by defining the transitive
> closure ("above") of the predicate on; then we introduce the
> constraint requiring that every block be located above the table.
> But this will only work if the transitive closure is treated as a
> statically defined fluent; we could not do this in the old C.
>
> Can you give such a "perfect" description of the blocks world in B++ ?
I am not sure. At least I do not immediately see how.
But remember, I crafted B++ just to better understand 'what is wrong with
action languages'.
In general I represent knowledge (in particular knowledge about dynamic
domains) in A-Prolog (and not in B++), and have of course no difficulty in
avoiding circular configurations by simply saying
:- block(B), not above(B,t).
To capture this I need a more powerful dialect of B.
There are many ways of doing that. At some point, for instance, Richard had
a notion of 'defined' fluent which will probably work here.
Let me suggest another variant of B, say B*, which I believe will also work.
SYNTAX:
Signature: inertial and non-inertial fluents (to simplify writing by fluents
I'll mean fluent literals), actions, and names of normative statements.
Statements:
1. D: Normally A causes F if P
2. D: Normally F if P
3. D: Normally impossible A if P
4. Q is an exception to D
5. D: Default F if P (where F is a non-inertial fluent)
The first three statements can be defeated only by the
listed exceptions. In this sense they correspond to 'strong' defaults as in
B++. (In terminology advocated by Son and I such statements, though
defeasible, are not defaults).
Statement (5) is a default. It can be defeated by defeating its conclusion,
as well as by exceptions. Notice, that (5) is applicable only to
non-inertial fluents.
Notice also that statements (1)-(3) with no
exceptions correspond to statements of B. We can make an agreement that
if 'normally' is omitted from a sentence then exceptions to it
are not allowed.
SEMANTICS.
(By translation.
I am violating Prolog agreement here. Capital letters
A,F,P,D are constants. Variable T ranges over [0,1]).
(a) Laws (1)-(3) are written as
h(F,1) :- occurs(A,0),
h(P,0),
not ab(D,0).
h(F,T) :- h(P,T),
not ab(D,T).
:- occurs(A,0),
h(P,0),
not ab(D,0).
(b) The law (5) is written as
h(F,T) :- h(P,T),
not ~h(F,T).
(c) Exception (4) to the law of form (1) is translated as
ab(D,0) :- h(Q,0).
~h(F,1) :- occurs(A,0),
h(Q,0),
h(P,0).
(Marcello noticed correctly that I missed h(P,0) in my
description of semantics of B++. So we know that someone else
is reading this.)
Exception to the law of form (2) is written as
ab(D,T) :- h(Q,T).
~h(F,T) :- h(Q,T),
h(P,T).
to the law (3) as
ab(D,T) :- h(Q,T).
and to the law (5) as
~h(F,T) :- h(Q,T),
h(P,T).
Adding the Inertia and standard rules to deal with '~' we obtain a program,
say, T(AD), where AD is an action description in B*.
The transition diagram is defined as in B++, i.e. the successor states
of (S0,A) correspond to answer sets of
T(AD) + {h(F,0) : F in S0} + o(A,0)
----------------------------------------------------------------------------
Going back to the block's world:
I'd define 'above' as a non-inertial fluent whose behavior is fully
determined by the laws:
above(A,B) if on(A,B).
above(A,B) if on(A,C), above(C,B).
default ~above(A,B).
false if block(B), ~above(B,t).
This is of course only a sketch, but I think it works.
----------------------------------------------------------------------------
B* seems to be a powerful language and
may deserve an investigation. In a sense it is a combination
of B+ and B++.
I can however come up with examples of
action descriptions which are simple in A-Prolog and are either impossible
or non-trivial in B*.
Any comments?
======
Date: Fri, 5 Oct 2001
From: Vladimir Lifschitz
To: Michael Gelfond
Your B* approach looks interesting. And I am curious about Richard's
notion of a defined fluent that you mention. This may be similar to
"statically determined" fluents that we are now adding to C. In fact,
at first we were even thinking of calling these fluents "defined", but
then decided against it. In many cases, the static laws characterizing
such a fluent provide its definition in terms of other fluents, but
generally this is not the case.
======
Date: Thu, 11 Oct 2001
From: Richard Watson
To: Vladimir Lifschitz
For me, the idea of a defined fluent came about when I found I often
wanted to express statements of the form
"l is true iff P1 or P2 or .. or Pn is true"
where each Pi is a set of literals.
In my dissertation, the corresponding definition propositions
have the form:
definition(l,P1).
...
definition(l,Pn)}.
I had the following restrictions on the use of such proposition:
1) if l is a defined literal, it neither it nor its negation can
belong to the head of a static or dynamic causal law.
2) for any fluent f, there may be definition propositions for f or neg(f)
but not both.
Semantically, definition propositions are simply a shorthand for a larger
set
of static causal laws:
{causes(l0,P1),...,causes(l0,Pm)} +
{causes(neg(l0),Q) | where Q is a minimal set of literals falsifying all
Pi's}.
Is this similar to what you are doing with "statically determined" fluents
in C?
======
Date: Thu, 11 Oct 2001
From: Vladimir Lifschitz
To: Richard Watson
Thank you for reminding me about the treatment of defined fluents
in your dissertation. Yes, there is some similarity with our definition
of statically determined fluents. Can your definitions be recursive? For
instance, can you treat the above relation in the blocks world as a
defined fluent?
The syntax that we plan to use is a bit different though: instead of a new
kind of propositions
definition(l,P)
we'll write the corresponding static laws. The fact that these static laws
are viewed as a logic-programming style definition of l is conveyed by
classifying l as "statically determined" in the definition of the language.
Accordingly, instead of prohibiting such fluents in the heads of both
static and dynamic laws, we prohibit them in the heads of dynamic laws only.
======
Date: Fri, 12 Oct 2001
From: Richard Watson
To: Vladimir Lifschitz
Yes, the syntax and semantics of definition propositions allowed them to
be recursive. However I'm not sure the translation to Logic Programming
I used is valid if they are.
======
Date: Tue, 20 Nov 2001
From: Pedro Cabalar
To: TAG
I've made an overall follow-up of the recent discussion about
limitations of action languages. The representational problems that
motivated the discussion are also present in PAL, since its only allowed
default is inertia. I had planned to extend this in two different ways:
(1) nonmonotonicity in the observations (specially thinking about the
initial situation)
(2) defeasible rules (for solving the qualification problem)
but this is still future work. From your discussion, it seems that both
problems are solved by defining (so-called) "static"/ "defined"/
"non-inertial" fluents, and applying them as
abnormality predicates.
I have a question: is this similar to the approach in [Baral&Lobo97]?
If I remember correctly, they used there 2 levels of abnormality: ab_1
for defeasible rules and ab_0 for inertia. Which would be the respective
differences w.r.t. your new proposals B++ and "new C"?
[Baral&Lobo97] C. Baral and J. Lobo. Defeasible Specifications in Action
Theories. Proc. of IJCAI'97 (pp 1441--1446). Nagoya, Japan.
---------
Apart from this question, I have also an objection about the particular
example of predicate above. In the beginning, I couldn't see the actual
need for considering above as non-inertial. I mean, for me, it is clear
that above(B,L) sometimes persists and sometimes is caused: i.e.,
inertia intuitively affects above!
Of course, I understand that defining inertia for above would lead to a
conflict with the rule asserting that above is false by default.
However, this seems to be a technical problem rather than a real reason
to supress inertia for above. The question is: can we still formalize
above as an inertial fluent?
I guess that this should be possible using other approaches. These are
my experiments in PAL, using some recently incorporated features, like
quantifiers.
My first attempt was this one:
options
not concurrent;
sets
block = [1,3];
location = block + {table};
actions
move: block -> location;
fluents
loc: block -> location;
clear: block -> boolean;
above: block x location -> boolean;
vars
B: block;
L:location;
rules
loc(B):=move(B);
clear(B):=not (exists C:block. C!=B and loc(C)=B);
above(B,L):=
loc(B)=L or
(exists C:block. C!=B and C!=L and loc(B)=C and above(C,L));
false if pert(move(B)) and not prev(clear(B));
false if not prev(clear(move(B)));
false if not above(B,table);
initially
loc(B):=table,not above(B,C),above(B,table),clear(B);
Note that both clear and above are "assigned" the truth of a whole
formula. For a boolean p, we could understand any
p:=F
as the pair of rules
p if F
not p if not F
Unfortunately this did not work. The simple execution:
do { move(1):=2; }
yielded no model when translated into stable models, whereas under wfs,
the answer left all the `above' ground instances undefined. The reason
is that there is an "active" negative cycle to establish whether
above(B,L) persists or not: i.e., the recursive definition leads to a
conflict.
Then I had the following idea: while loc(B)=L persists true (it is not
altered) the corresponding above(B,L) should also persist true (i.e.,
its rule should be disabled), regardless any modification on the
location of other blocks. This kind of reasoning can be now done in PAL
by using what I call "safe" (or "persistence shortcircuit") operators
`&&' `||' `exists_' and `forall_'. The corresponding change in the
definition of above would simply be:
above(B,L):=
loc(B)=L ||
(exists_ C:block. C!=B && C!=L && loc(B)=C && above(C,L));
Something similar can be done for clear
clear(B):=not (exists_ C:block. C!=B && loc(C)=B);
though it is not necessary to solve the conflict. Now, the execution
do {move(1):=2; move(3):=1; }
leads to:
1)
move(1):=2
loc(1):=2
clear(2):=false
clear(3):=true
above(1,1):=false
above(1,table):=true
above(1,2):=true
above(1,3):=false
2)
move(3):=1
loc(3):=1
clear(1):=false
above(3,1):=true
above(3,table):=true
above(3,2):=true
above(3,3):=false
both under wfs and stable models. The answer shows all the relevant or
"caused" facts. At each situation, non-displayed fluents persist with
their previous value. Note for instance how the second block movement
does not alter above(1,2) or above(1,table). i.e., these facts persist.
Of course, I know that the experiments are not sufficiently explained,
but I just wanted to see whether you find these results interesting or
at least reasonable.
======
Date: Tue, 27 Nov 2001
From: Vladimir Lifschitz
To: Pedro Cabalar
This is a reply to the two questions that you raised in a recent message
to TAG.
1. Is the idea of a statically determined fluent similar to the
difference between two kinds of abnormality (ab_1 for defeasible
rules and ab_0 for inertia) in the IJCAI-97 paper by Baral and Lobo?
I don't see any close relationship here. A detailed discussion of
statically determined fluents is available now in Section 4 of the paper
"Nonmonotonic causal theories" mentioned in my previous message to TAG,
and I hope that this will make it easier to compare our proposal with
others.
2. Is it necessary to treat the above predicate in the blocks world as
non-inertial?
You may very well be right that this is not necessary. After all, the
commonsense law of inertia is merely a default, and a default can always
be disabled. But, once we postulated a definition of a fluent F in terms
of other fluents, it would be strange, it seems to me, to postulate
inertia for F. The definition of F will allow us to compute the value of
F after performing an action on the basis of the values of other fluents
in the same state without using inertia. Assuming inertia for a defined
fluent is sometimes harmful, sometimes not, but it is never useful!
======
Date: Wed, 12 Dec 2001
From: Michael Gelfond
To: Pedro Cabalar
Pedro:
What is the relationship between B* and the ADC language of
[Baral&Lobo97] C. Baral and J. Lobo. Defeasible Specifications in Action
Theories. Proc. of IJCAI'97 (pp 1441--1446). Nagoya, Japan.
M. (You actually asked about B++ but B* is probably more interesting).
Well, ideologically both languages are very close.
As far as I know their paper contains the first published account of the idea
of defining the transition function of an action language via
the notion of answer set.
This is of course what I am doing in defining B* and other similar languages.
Unfortunately, I cannot answer your question more precisely.
I suspect that B* is an extension of ADC but cannot say for sure.
After your question I spend some time looking at the paper but
the end of semester is too hectic a time.
One of the problems is that their translation to logic programs
looks somewhat strange to me now.
(Chitta may remember a rational for using two ab's and for having
the same ab's in the bodies of different defaults, etc).
If someone decides to take B* or a variant seriously this question of
course should be answered. (If this happens please let me know - I
think that some study of B* will be useful and will
be glad to take part in it.)
Pedro.
Apart from this question, I have also an objection about the particular
example of predicate above. In the beginning, I couldn't see the actual
need for considering above as non-inertial. I mean, for me,
it is clear
that above(B,L) sometimes persists and sometimes is caused: i.e.,
inertia intuitively affects above!
Of course, I understand that defining inertia for above would lead to a
conflict with the rule asserting that above is false by default.
However, this seems to be a technical problem rather than a real reason
to suppress inertia for above.
The question is: can we still formalize
above as an inertial fluent?
M. We sure can.
Suppose instead of statement of type (5) in B* I allow
5. D: Default F if P (where F is an arbitrary fluent)
Then all I need to add to my translation is a statement saying
that this default is preferred to inertia. To make the translation short
I'll write the inertia as
h(F,T+1) :- h(F,T),
not ab(d1(F),T),
not ~h(F,T+1).
~h(F,T+1) :- h(F,T),
not ab(d2(F),T),
not h(F,T+1).
and for each default (5) such that F is a fluent add:
ab(d2(F),T) :- h(P,T).
If head of default (5) is ~F add
ab(d1(F),T) :- h(P,T).
Now I do not need to worry if F is inertial or not.
Is that what you wanted?
P. it is clear that above(B,L) sometimes persists and
sometimes is caused: i.e., inertia intuitively affects above!
M. Here I believe is the root of the problem. For you inertia
seems to be something which really (physically) affects the fluent.
When I say that fluent is inertial it simply means that in my
knowledge base the fluent's truth values are defined by the
inertia axiom and its exceptions.
You seem to be more interested in modeling 'physical' causality
and 'physical' inertia while I am mainly concerned with finding
convenient ways of representing knowledge. The latter representation of
the 'above' maybe more suitable from your perspective, while from mine
it is redundant and hence less elegant. (Judging by his
last message Vladimir shares this perspective.)
Is this a reasonable analysis?
P. Of course, I understand that defining inertia for above would lead to a
conflict with the rule asserting that above is false by default.
However, this seems to be a technical problem rather than a real reason
to suppress inertia for above.
M. I am not sure I follow that. Can you elaborate?
P. These are my experiments in PAL, using some recently
incorporated features, like quantifiers.
My first attempt was this one:
options
not concurrent;
sets
block = [1,3];
location = block + {table};
actions
move: block -> location;
fluents
loc: block -> location;
clear: block -> boolean;
above: block x location -> boolean;
vars
B: block;
L:location;
rules
loc(B):=move(B);
clear(B):=not (exists C:block. C!=B and loc(C)=B);
above(B,L):=
loc(B)=L or
(exists C:block. C!=B and C!=L and loc(B)=C and above(C,L));
false if pert(move(B)) and not prev(clear(B));
false if not prev(clear(move(B)));
false if not above(B,table);
initially
loc(B):=table,not above(B,C),above(B,table),clear(B);
Note that both clear and above are "assigned" the truth of a whole
formula. For a boolean p, we could understand any
p:=F
as the pair of rules
p if F
not p if not F
Unfortunately this did not work. The simple execution:
do { move(1):=2; }
yielded no model when translated into stable models, whereas under wfs,
the answer left all the `above' ground instances undefined. The reason
is that there is an "active" negative cycle to establish whether
above(B,L) persists or not: i.e., the recursive definition leads to a
conflict.
M. I think I follow this, even though some English descriptions of
the rules would help.
What do you mean when you say this didn't work?
Is it a problem with the semantics of PAL or with the translation into
logic programs?
In your terminology, is the problem 'real' or 'technical'?
The solution you suggest does not seem 'natural' to me
but more detailed description may easily change this impression.
P. I just wanted to see whether you find these results interesting or
at least reasonable.
M. If they help you to understand something then of course they are
reasonable. For me to really answer your question though I need to know
what is the goal you are trying to achieve.