• No results found

3.2 ConGolog

3.2.1 A Transition Semantics

Formally, the semantics of ConGolog is defined using a so-called transition semantics, which de-

fines single steps of computation. There is a relation, denoted by the predicate Trans(σ, s, δ, s0),

that associates with a given program σ and situation s a new situation s0 that results from

executing σ’s first action in s, and a new program δ that represents what remains of σ after

having performed that action. Furthermore, one needs to define which configurationshσ, si

are final, meaning that the computation can be considered completed when a final configura- tion is reached. This is denoted by the predicate Final(σ, s). Note that the use of a transition semantics necessitates the reification of programs as first order terms in the logical language (cf. [dGLL00] and Appendix A). To simplify the discussion, we postpone the introduction of procedures which necessitates the use of second-order logic.

The predicate Final is characterized by the following set of axioms. The term φ[s] denotes the formula obtained by substituting the situation variable s for all occurrences of now in fluents appearing in φ (cf. [dGLL00] and Appendix A).

Final(α, s)≡ False , where α is a primitive action

Final(nil, s)≡ True, where nil is the empty program

Final(φ?, s)≡ False

Final([σ1, σ2], s)≡ Final(σ1, s)∧ Final(σ2, s)

Final(if(φ, σ1, σ2), s)≡ φ[s] ∧ Final(σ1, s)∨ ¬φ[s] ∧ Final(σ2, s)

Final(while(φ, σ), s)≡ ¬φ[s] ∨ Final(σ, s)

Final(σ1 ii σ2, s)≡ Final(σ1, s)∧ Final(σ2, s)

Final(σ1|σ2, s)≡ Final(σ1)∨ Final(σ2)

Final(πx.σ, s)≡ ∃v.Final(σx

v, s)

Final(σ∗, s)≡ True

Final(σ1 || σ2)≡ Final(σ1)∧ Final(σ2)

Final(σ||, s)≡ True

4We remark that non-concurrent GOLOG [LRL+97] considers non-synchronized versions of the if-then-else

3.2. CONGOLOG 45 Let us first consider when a deterministic program is final. A program that consists of a primitive action α or a test φ? is never final. On the other hand, the empty program nil is always final. A conditional if(φ, σ1, σ2) is final if φ holds and σ1 is final, or if φ is false and σ2

is final. A sequence [σ1, σ2] is final if and only if both σ1 and σ2 are final. A while(φ, σ) loop

is final if φ is false or if σ is final. The concurrent, prioritized execution of two programs is

final if and only if both programs are final. As for the nondeterministic instructions, σ1|σ2 is

final if any nondeterministic branch σi is final. πx.σ is final if there exists a binding v for x

such that σvx is final, where σvx is obtained from σ by substituting x with v. σ∗ is final, since

it is allowed to execute 0 times. Similarly for σ||. Finally, σ1 || σ2 is final if and only if both

σi are final.

The following set of axioms characterizes the predicate Trans. Similar to φ[s], α[s] denotes the action obtained by substituting the situation variable s for all occurrences of now in functional fluents appearing in α (cf. [dGLL00] and Appendix A).

Trans(nil, s, δ, s0)≡ False

Trans(α, s, δ, s0)≡ Poss(α[s], s) ∧ δ = nil ∧ s0 = do(α[s], s)

Trans(φ?, s, δ, s0)≡ φ[s] ∧ δ = nil ∧ s0 = s Trans([σ1, σ2], s, δ, s0)≡

∃γ.Trans(σ1, s, γ, s0)∧ δ = [γ, σ2]∨ Final(σ1, s)∧ Trans(σ2, s, δ, s0)

Trans(if(φ, σ1, σ2), s, δ, s0)≡ φ[s]∧ Trans(σ1, s, δ, s0)∨ ¬φ[s] ∧ Trans(σ2, s, δ, s0) Trans(while(φ, σ), s, δ, s0)≡ ∃γ.Trans(σ, s, γ, s0)∧ φ[s] ∧ δ = [γ, while(φ, σ)] Trans(σ1 ii σ2, s, δ, s0)≡ ∃γ.δ = (γ ii σ2)∧ Trans(σ1, s, γ, s0)∨ ∃γ.δ = (σ1 ii γ) ∧ Trans(σ2, s, γ, s0)∧ ∀γ0, s00.¬Trans(σ1, s, γ0, s00)

Trans(σ1|σ2, s, δ, s0)≡ Trans(σ1, s, δ, s0)∨ Trans(σ2, s, δ, s0)

Trans(πx.σ, s, δ, s0)≡ ∃v.Trans(σx v, s, δ, s) Trans(σ∗, s, δ, s0)≡ ∃γ.δ = [γ, σ∗]∧ Trans(σ, s, γ, s0) Trans(σ1 || σ2, s, δ, s0)≡ ∃γ.δ = (γ || σ2)∧ Trans(σ1, s, γ, s0)∨ ∃γ.δ = (σ1 || γ) ∧ Trans(σ2, s, γ, s0) Trans(σ||, s, δ, s0)≡ ∃γ.δ = (γ || σ||)∧ Trans(σ, s, γ, s0)

As before, we first consider the deterministic instructions. Intuitively, a program that consists of a single atomic action α in a situation s results in the execution of α[s] with an empty remaining program if and only if α[s] is executable in s. A test φ? succeeds if φ[s] holds, leaving nothing to be done, or is blocked, meaning that it cannot result in a transition. The

execution of [σ1, σ2] in s may result in any successor situation that could be reached by the

execution of σ1, with remaining program [γ, σ2], where γ is what remains of σ1; or, if σ1

is final in s, it just corresponds to the execution of σ2. The execution of if(φ, σ1, σ2) in s

corresponds to the execution of σ1 if φ is true in s, else it corresponds to the execution of σ2.

A while(φ, σ) loop may only result in a successor configuration if φ is true, in which case the

σ1 whenever possible; however, if σ1 is blocked it executes σ2.

The execution of the nondeterministic instruction (σ1|σ2) in s can result in any successor

configuration that can be reached through the execution of σ1 or σ2 in s. The execution of

πx.σ can result in a successor configuration hδ, s0i if there is a v such that the execution of

any σx

v can result inhδ, s0i. Here, σvxis the program resulting from σ by substituting x with v.

The execution of σ∗ in s can result in a new situation s0 if the execution of σ can do so. The

remaining program then consists of the sequence [γ, σ∗], where γ is what remains of σ after

the transition from s to s0. Similarly, the execution of σ|| in s can result in a new situation s0

if the execution of σ can do so. This time, the remaining program consists of the concurrent

execution of γ and σ||. Finally, (σ1 || σ2) may result in any successor situation which can be

reached by a single step of any σi. The remaining program then consists of the concurrent

execution of what remains of σi, and the other (unmodified) process.

A final situation s0 reachable after a finite number of transitions from a starting situation

s is identified with the situation resulting from a possible execution trace of program σ,

starting in situation s. This is captured by the predicate Do(σ, s, s0), which is defined in

terms of T rans∗, the transitive closure of T rans:

Do(σ, s, s0)≡ ∃δ.T rans∗(σ, s, δ, s0)∧ F inal(δ, s0) Trans∗(σ, s, δ, s0)≡ ∀T [... ⊃ T (σ, s, δ, s0)]

where the ellipsis stands for the universal closure of the conjunction of the following formulas: T (σ, s, σ, s)

Trans(σ, s, σ∗, s∗)∧ T (σ∗, s∗, δ, s0)⊃ T (σ, s, δ, s0)

Given a program δ, proving that δ is executable in the initial situation then amounts to

proving Γ|= ∃s.Do(δ, S0, s), where Γ consists of the above axioms for ConGolog together with

a situation calculus basic action theory. The following proposition (Lemma 4 from [dGLL00]) turns out to be quite useful in doing so. Intuitively, it says that to show that Trans∗(σ, s, δ, s0) holds, it is sufficient to show that there is a sequence of transitions leading fromhσ, si to hδ, s0i.

Proposition 1 : Let AX be the foundational axioms of the situation calculus together

with the definitions of Trans, Final and Trans∗. Then for every model M of AX, M |=

Trans∗(σ, s, δ, s0) if and only if there exist σ1, s1, ..., σn, sn such that σ1 = σ, s1 = s, σn =

δ, sn= s0 and M |= Trans(σi, si, σi+1, si+1) for i = 1, ...n− 1.

3.2.2 An Example

To illustrate the use of ConGolog, let us go back to the coffee delivery example of the previous section. Suppose we want to instruct the robot to subsequently serve coffee to all who have issued a coffee request. This can be specified by the following ConGolog plan:

Πdeliv= while(. ∃r.CoffeeRequest(r),

[gotoRoom(nextRoom), giveCoffee(robotLoc)])

A word on notation: throughout this thesis, we will use terms of the form Πname to denote

plans. Note that we have not yet defined the semantics of procedures; accordingly we consider Πdeliv as an abbreviation. Πdeliv makes use of the defined functional fluent nextRoom to

3.2. CONGOLOG 47

determine the order in which coffee requests are to be fulfilled. nextRoom is defined as

follows:

nextRoom(s) = r≡ r = nil ∧ ∀r0.¬CoffeeRequest(r0, s)∨

CoffeeRequest(r, s)∧ ¬∃r0.[CoffeeRequest(r0, s)∧ roomOrder(r0, r)]. (3.12)

Here, the predicate roomOrder defines an (arbitrary) total ordering on the room names. For means of simplicity, we use the following definition of roomOrder:

roomOrder(r0, r)≡r0 = R1∧ r ∈ {R2, R3, R4}∨

r0 = R2∧ r ∈ {R3, R4}∨

r0 = R3∧ r ∈ {R4}.

(3.13)

Let Γ be the basic action theory describing the coffee delivery domain from the previous

section together with the axioms defining Trans, Final, Trans∗ and Do from this section, the

definitions of nextRoom and roomOrder and the axioms needed for the encoding of programs as first-order terms (cf. [dGLL00] and Appendix A). Then from Γ we can deduce that the

execution of Πdeliv in S0 results in a situation (an execution trace) where all requests have

been satisfied:

Γ|= ∃s.Do(Πdeliv, S0, s)∧ ¬∃r.CoffeeRequest(r, s)∧

s = do([gotoRoom(R2), giveCoffee(R2), gotoRoom(R4), giveCoffee(R4)], S0).

Proof: Although the proof is straightforward, it is quite laborious. By Proposition 1, to

prove that do([gotoRoom(R2), giveCoffee(R2), gotoRoom(R4), giveCoffee(R4)], S0) is an exe-

cution trace of Πdeliv in S0 we have to show that there is a sequence of transitions from S0

to do([gotoRoom(R2), giveCoffee(R2), gotoRoom(R4), giveCoffee(R4)], S0). Furthermore, we

have to show that the last configuration is final. From the initial state description (Ax- iom 3.7), we get:

CoffeeRequest(R2, S0). (3.14)

Hence,∃r.CoffeeRequest(r, S0). From this and the definition of Final:

¬Final(Πdeliv, S0). (3.15)

From the definition of Trans regarding while-loops:5

Trans(while(∃r.CoffeeRequest(r), [gotoRoom(nextRoom), giveCoffee(robotLoc)]), S0, δ, s0)≡ ∃γ.Trans([gotoRoom(nextRoom), giveCoffee(robotLoc)], S0, γ, s0)∧ ∃r.CoffeeRequest(r, S0)∧ δ = [γ, while(∃r.CoffeeRequest(r), [gotoRoom(nextRoom), giveCoffee(robotLoc)])]. (3.16)

From the initial state description (Axiom 3.7), the definition of nextRoom (Axiom 3.12) and the definition of roomOrder (Axiom 3.13):

nextRoom(S0) = R2. (3.17)

5To be more precise, we also need the predicate Holds(φ, s), which is used to evaluate reified conditions

From 3.17, the action precondition for gotoRoom (Axiom 3.8) and the definition of Trans regarding primitive actions:

Trans(gotoRoom(nextRoom), S0, δ, s0)≡ s0 = do(gotoRoom(R2), S0)∧ δ = nil. (3.18)

From 3.18 and the definition of Trans regarding sequences:

Trans([gotoRoom(nextRoom), giveCoffee(robotLoc)]), S0, δ, s0)≡

s0 = do(gotoRoom(R2), S0)∧ δ = [nil, giveCoffee(robotLoc)]. (3.19)

From 3.14, 3.16 and 3.19 we get the following, which shows that there is a transition from S0

to do(gotoRoom(R2), S0).

Trans(while(∃r.CoffeeRequest(r),

[gotoRoom(nextRoom), giveCoffee(robotLoc)]), S0, δ, s0)≡

δ = [[nil, giveCoffee(robotLoc)], while(∃r.CoffeeRequest(r),

[gotoRoom(nextRoom),

giveCoffee(robotLoc)])]∧

s0 = do(gotoRoom(R2), S0).

(3.20)

Let S1= do(gotoRoom(R. 2), S0). From the definition of Final:

¬Final([[nil, giveCoffee(robotLoc)], Πdeliv], S1). (3.21)

From the definition of Trans regarding sequences and 3.21:

Trans([[nil, giveCoffee(robotLoc)], Πdeliv], S1, δ, s0)≡

∃γ.Trans([nil, giveCoffee(robotLoc)], S1, γ, s0)∧

δ = [γ, Πdeliv].

(3.22)

From the definition of Trans regarding sequences and the fact Final(nil, s):

Trans([nil, giveCoffee(robotLoc)], s, δ, s0)≡ Trans(giveCoffee(robotLoc), s, δ, s0). (3.23)

From the successor state axiom for robotLoc (Axiom 3.10):

robotLoc(S1) = R2. (3.24)

From 3.24, the action precondition axiom for giveCoffee (Axiom 3.9) and the definition of Trans regarding primitive actions:

Trans(giveCoffee(robotLoc), S1, δ, s0)≡

s0= do(giveCoffee(R2)], S1)∧ δ = nil.

(3.25) From 3.25 and 3.23 and 3.22 we get the following, which shows that there is a transition from S1 to do(giveCoffee(R2), S1):

Trans([[nil, giveCoffee(robotLoc)], Πdeliv], S1, δ, s0)≡

δ = [nil, Πdeliv]∧ s0 = do(giveCoffee(R2), S1).

(3.26)

Let S2 = do(giveCoffee(R. 2), S1). From the successor state axiom for CoffeeRequest (Ax-

iom 3.11) and the initial state description (Axiom 3.7):

3.2. CONGOLOG 49 From 3.27 and the definition of Final:

¬Final([nil, Πdeliv], S2). (3.28)

From the definition of Trans regarding sequences and the fact Final(nil, s): Trans([nil, Πdeliv], S2, δ, s0)≡

Trans(Πdeliv, S2, δ, s0).

(3.29) From 3.29, 3.27 and the definition of Trans regarding while-loops:

Trans([nil, Πdeliv], S2, δ, s0)≡

Trans([gotoRoom(nextRoom), giveCoffee(robotLoc)], S2, γ, s0)∧

δ = [γ, Πdeliv].

(3.30)

From the definition of nextRoom (Axiom 3.12), the successor state axiom for CoffeeRequest (Axiom 3.11) and the definition of roomOrder (Axiom 3.13):

nextRoom(S2) = R4. (3.31)

From 3.30, 3.31, the action precondition axiom for gotoRoom (Axiom 3.8) and the def-

inition of Trans we get the following, which shows that there is a transition from S2 to

do(gotoRoom(R4), S2):

Trans([nil, Πdeliv], S2, δ, s0)≡

s0 = do(gotoRoom(R4), S2)∧

δ = [[nil, giveCoffee(robotLoc)], Πdeliv].

(3.32)

Let S3= do(gotoRoom(R. 4), S2). From the definition of Final:

¬Final([[nil, giveCoffee(robotLoc)], Πdeliv], S3) (3.33)

From the successor state axiom for robotLoc (Axiom 3.10):

robotLoc(S3) = R4 (3.34)

From the definition of Trans regarding sequences and 3.33:

Trans([[nil, giveCoffee(robotLoc)], Πdeliv], S3, δ, s0)≡

∃γ.Trans([nil, giveCoffee(robotLoc)], S3, γ, s0)∧

δ = [γ, Πdeliv].

(3.35)

From the action precondition axiom for giveCoffee (Axiom 3.9), 3.34 and the definition of Trans:

Trans([nil, giveCoffee(robotLoc)], S3, δ, s0)≡

s0= do(giveCoffee(R4), S3)∧ δ = nil.

(3.36)

From 3.35 and 3.36, we get the following, which shows that there is a transition from S3 to

do(giveCoffee(R4), S3):

Trans([[nil, giveCoffee(robotLoc)], Πdeliv], S3, δ, s0)≡

Let S4 = do(giveCoffee(R. 4), S3). We have now shown that there is a sequence of transi-

tions from S0 to S4 = do([gotoRoom(R2), giveCoffee(R2), gotoRoom(R4), giveCoffee(R4)], S0).

From 3.20, 3.26, 3.32, 3.37 and Proposition 1:

Trans∗(Πdeliv, S0, [nil, Πdeliv], S4). (3.38)

In order to show that S4 is an execution trace of Πdeliv, we still have to show that the

configuration reached is final. From the successor state axiom for CoffeeRequest (Axiom 3.11) and the initial state description (Axiom 3.7):

¬∃r.CoffeeRequest(r, S4). (3.39)

From 3.39 and the definition of Final regarding while-loops:

Final(while(∃r.CoffeeRequest(r),

[gotoRoom(nextRoom), giveCoffee(robotLoc)]), S4).

(3.40) From 3.40, the fact Final(nil, s) and the definition of Final regarding sequences:

Final([nil, Πdeliv], S4). (3.41)

Finally, from the definition of Do, 3.38 and 3.41, we can conclude that S4 is an execution

trace of Πdeliv in S0:

Γ|= Do(Πdeliv, S0, S4). (3.42)

This, together with 3.39, finishes the proof. 2

As the above proof illustrates, proving that the execution of a program results in a par- ticular execution trace is a straightforward but laborious task. In general, it is suggestive to make use of a ConGolog implementation instead of calculating execution traces by hand. In fact, all example executions presented in this thesis were computed using the prototypical implementations described in Chapter 8. Accordingly, in the remainder of this thesis we will only provide some (informal) arguments as to why a program results in a particular execution trace.