Dynamo with Constraint Handling 1 Dynamic ... - CiteSeerX

4 downloads 0 Views 214KB Size Report
basis of the Dynamo programming language, and then takes on the task of ... In Van Eijck 5, 3] an executable process interpretation for rst order logic was ...
Dynamo with Constraint Handling Jan van Eijck CWI and ILLC, Amsterdam Abstract The paper gives a sketch of the executable process interpretation of rst order logic that lies at the basis of the Dynamo programming language, and then takes on the task of improving its execution mechanism by means of constraint storage.

1 Dynamic Interpretation of FOL In Van Eijck [5, 3] an executable process interpretation for rst order logic was proposed and shown to be a faithful approximation of the dynamic interpretation procedure for rst order formulas familiar from natural language semantics (see Barwise [2], Groenendijk and Stokhof [6]), extended with constructs for bounded choice and bounded iteration. This gives rise to a paradigm of dynamic logic programming, combining imperative strength with a declarative relational semantics that remains very close to rst order logic. The [5] version of dynamic logic programming employs states consisting of triples ( ; ga ; la), where is a ( nite or in nite) valuation, ga is a register of global variables, and la a register of local variables. We brie y review this mechanism here, and then extend it, by incorporating stacks of unresolved literals in the states. Let a rst order signature be given. We assume that variables can be built from a set Var of initial variables by means of appending indices. Let f and P range over the function and relation symbols, with arities n as speci ed by the signature. We assume that that terms range over the natural numbers, and that f and P denote recursive functions and predicates on N . The terms and formulas of dynamic FOL over this signature are given by:

v N t 

::= ::= ::= ::=

var j v[t] 0 j 1 j 

v j ft1    tn ? j Pt1   Stnv j t1 =: t2 Sj 9vv j : j (1 ; 2 ) j (1 [ 2 ) j N j t j N1 ::N2  j t1 ::t2  Note the di erences with the standard syntax of FOL. The quanti er pre x 9v has become a formula in

its own right. The familiar sign for conjunction ^ has been replaced by ;, to indicate that the operation of `sequential composition' is in general not commutative. The familiar disjunction sign _ has been replaced S by [, to indicate that disjunction is a commutative choice operation. Finally, the constructs N and vN1 ::N2  haveSbeen added, to express bounded choice and bounded iteration, respectively. The constructs t and vt1 ::t2  allow bounds to be computed at runtime (i.e., to depend on previous computation), because the values of t, t1 , t2 depend on the current evaluation state. 1

We assume that valuations are functions from V = fVari j i 2 N g to the domain M of a model M = (M; I ). The interpretation of terms and formulas in a model M = (M; I ), under a valuation , is given by the following de nition. We use v for: valuations and di er at most in the value they assign to the variable v. 

0

0

De nition 1 (Dynamic Interpretation of FOL in a model M = (M; I )) (var[t1 ]    [tn ]) := a(vart 1 ;::: ;t n ) (ft1    tn ) := I (f )t 1    t n [(?)]( ) := ; fag if (t 1 ; : : : ; t n ) 2 I (P ) [(Pt1    tn )]( ) := otherwise. ; f a g if t 1 = t 2 : [(t1 = t2 )]( ) := ; otherwise. [(9v)]( ) := fa 2 M V j a v ag fag if [()]( ) = ; [(:)]( ) := otherwise. S; [(1 ; 2 )]( ) := f[(2 )]( ) j a 2 [(1 )]( )g [(1 [ 2 )]( ) := [(1 )]( ) [ [(2 )]( ) [(0 )]( ) := fag 0

0

0

[(N +1 )]( ) [(t )]( ) [([vN1 ::N2 )]( ) [([vt1 ::t2 )]( )

0

:= [(; N )]( ) := [(t )]( ) [(v = N1 ; )]( ) [    [ [(v = N2 ; )]( ) if N1  N2 := otherwise. ; [ ( v = t ;  )]( ) [    [ [ ( v = t ;  )]( ) if t 1  t 2 1 2 := ; otherwise.

The advantages of dynamic FOL as a programming language are found in the close connection with standard FOL. See Van Eijck [5, 3] for de nitions of weakest preconditions of dynamic readings of FOL formulas.

2 Executing FOL Formulas To see that the dynamic FOL interpretation given above will not do for purposes of computation, note that the clause for quanti cation makes it computationally unfeasible. In the computational interpretation of FOL we therefore change the quanti er action as follows. Instead of letting the quanti er action 9x perform its full duty, we split the action 9x in two tasks: (1) throwing away the old value of x, and (2) identifying appropriate new values for x. In the absence of further information, any value for x is as good as another, so task (2) boils down to picking a random new object. On in nite domains any attempt to perform task (2) immediately will cause an in nite branching transition. Computationally this is out, and therefore we have to postpone this task. We relegate the duty of nding an appropriate new value for x to an appropriate identifying statement for x further on. This procedure is familiar from constraint programming. A source of inspiration for this move, and thus for the computational interpretation of FOL is Alma-0, a hybrid language for imperative programming mixed with logic programming developed by Apt c.s. [1]. We allow nite valuations as inputs and S outputs of FOL formulas. Let Var be given. and let V be the set of variables fVari j i 2 N g Let A := X V N X , let  be the empty partial valuation (the only member of N ), and let  be an object not in A. 



;

2

Figure 1: Executable Process Interpretation of FOL (1): The treatment of Quanti cation and Equality

9v

v 2= dom ( ) v ( ; ga ; la) ?! ( ; ga ; la [ fvg) v 2 dom ( ) v ( ; ga ; la) ?! ( ? fv=v g; ga; la [ fvg) t1 =: t2 a-closed and t 1 = t 2 1 =: t2 ( ; g a ; la ) ( ; ga ; la ) t?! t1 =: t2 an -assignment with t1  v; v ="; t 2 =#; v 2 la 1 =: t2 ( [ fv=t g; g a ; la ) ( ; ga ; la ) t?! 2 : t1 = t2 an -assignment with t1  v; v ="; t 2 =#; v 2= la 1 =: t2 ( [ fv=t g; g a [ fv g; la ) ( ; ga ; la ) t?! 2 : t1 = t2 an -assignment with t2  v; v ="; t 1 =#; v 2 la 1 =: t2 ( [ fv=t g; g a ; la ) ( ; ga ; la ) t?! 1 : t1 = t2 an -assignment with t2  v; v ="; t 1 =#; v 2= la 1 =: t2 ( [ fv=t g; g a [ fv g; la ) ( ; ga ; la ) t?! 1 : t1 = t2 not an -assignment and not -closed 1 =: t2  ( ; ga ; la) t?! 9

9

t1 =: t2

3

Figure 2: Executable Process Interpretation of FOL (2): The Other Rules

 propagation ? Pt1    tn

  ?! 

no ?! transitions from ( ; ga ; la ) Pt1    tn a-closed and (t 1 ; : : : ; t n ) 2 I (P ) t1 tn ( ; ga ; la) ( ; ga ; la ) P ?! Pt1    tn not a-closed t1 tn  ( ; ga ; la ) P ?! ?





:

 there are no b with ( ; dom ( ); ;) ?! b  ( ; ga ; la ) ?! ( ; ga ; la) :

 there are ?! transitions for ( ; dom ( ); ;); but all unsafe.  ( ; ga ; la ) ?!  :

1 2 a ?! b b ?! c 1 ;2 a ?! c i b i 2 f1; 2g a ?! 1 2 a ?! b

seq composition union

[

N

  a ?! b b ?! c 0 N +1 bounded iteration a ?! a a ?! c N  ( ; ga ; la) ?! b =" t t =N t t   ( ; ga ; la) ?!  ( ; ga ; la) ?! b t 1 =" t 2 =" v v   t ::t t ::t 1 2  1 2  bounded choice ( ; ga ; la ) ?! ( ; ga ; la ) ?! v = j ;  ( ; ga ; la) ?! b t1 = M; t 2 = N; M  j  N v t1 ::t2  a a ( ; g ; l ) ?! b [

[

[

4

If a 2 N X , for X  V , then a term t is -closed if all variables in t are in X , an atom Pt1    tn is -closed if all ti are -closed, and an identity t1 =: t2 is -closed if both of t1 ; t2 are. If a 2 M X we call X the domain of . Use " for `unde ned' and # for `de ned'. Term interpretation in model N = (N ; I ) with respect to valuation has now to take the possibility into account that the value of the term under is unde ned.  a(v) if v is a-closed v :=  " otherwise I (f )t1    t n if t1 ; : : : ; tn a-closed (ft1    tn ) := " otherwise

An identity t1 =: t2 is an -assignment if either t1  v, t 1 =", t 2 =#, or t2  v, t 1 =#, t 2 =". Treatment  of negation should be phrased in such a way that the so-called forward property is guaranteed. a?! b  has the forward property if for all a  a it holds that there is a b  b with a ?!b . 0

0

0

0

:

x=1 For example, we have  ?! f:x=1g, but we cannot conclude from this that :x =: 1 fails for input . On x=1 the other hand, from fx=1g ?! fx=1g we can conclude that :x =: 1 fails for input fx=1g. To ensure that the forward property holds, we have to keep track of variables relevant to a particular path taken by the computation. To this end, we introduce two distinguished registers:

 g for the set of global variables that get assigned along a computation path (global variables are

like the free variables of FOL),  l for the set of local variables that get declared and possibly assigned along a computation path (local variables are dynamically bound variables within a certain context: variables of which the value is a ected by a preceding quanti er action in that context).

A proper state is a triple consisting of a valuation a 2 A, a global store ga  V , and a local store la  V . The improper state is the item . We will refer to states as a, b and c, and to proper states as ( ; ga ; la) and (b; gb ; lb ).  We say that a transition ( ; ga ; la ) ?! (b; gb; lb ) is safe if la [ gb  dom ( ), or equivalently, if la  dom ( ) a b and g = g . We say that b is safe for ( ; ga ; la) if b = (b; gb ; lb ) (i.e., b 6= ), la  dom ( ) and ga = gb. Note that in the special case where la = ; the requirement for safety boils down to just ga = gb . In the treatment of negation :, we have to make sure that if new values are computed inside , this occurs only for variables v that are within the dynamic scope of quanti er occurrence 9v within . If : is to be computed in a state ( ; ga ; la), we try to compute  in a state ( ; dom ( ); ;). If inside  an assignment takes place to a variable v, then there are two cases:

 The variable is in the dynamic scope of a quanti er occurrence 9v, with 9v within . This means that at the point within the computation of  where the relevant occurrence of 9v gets processed, v

is marked as local. Subsequently, when v gets assigned its value, the set of global variables remains una ected, witnessing the fact that the assignment is safe.  The variable is not in the dynamic scope of a quanti er occurrence 9v, with 9v within . In this case the variable v at the point of assignment will not be in the set of local variables, for this set was initialized to ; at the start of the computation of . Therefore, the variable v is marked as global, to `witness the risk', so to speak. The full set of rules for the executable interpretation of FOL is given in Figures 1 and 2. See the papers mentioned above for illustration and further discussion, and for proofs of the following facts: 5

 The conditions la  dom ( ) and ga = gb together guarantee the forward property for  ( ; ga ; la ) ?! (b; gb ; lb ):  The executable interpretation is faithful to the dynamic interpretation of FOL in the following

sense: (1) if the executable process interpretation computes an answer valuation, then that answer is correct according to the dynamic FOL interpretation, and (2) if there are no answers according to the executable process interpretation then there are no answers according to the dynamic FOL interpretation.

3 Improving the Execution Mechanism To illustrate a aw of the Dynamo execution mechanism, it is convenient to write A[[]]B for  B = fb j a ?! b; a 2 Ag:

Consider the following examples. (x = 2 [ x = 3); (y = x + 1 [ 2 = y); (2  x = 3  y) (1) (y = x + 1 [ 2 = y); (x = 2 [ x = 3); (2  x = 3  y) (2) For the rst example, we get the following (for simplicity we leave out the global and local registers): fg[[(x = 2 [ x = 3); (y = x + 1 [ 2 = y); (2  x = 3  y)]] = fg[[x = 2 [ x = 3]] [[(y = x + 1 [ 2 = y); (2  x = 3  y)]] = ffx=2g; fx=3gg[[(y = x + 1 [ 2 = y); (2  x = 3  y)]] = ffx=2g; fx=3gg[[y = x + 1 [ 2 = y]][[2  x = 3  y]] = ffx=2; y=3g; fx=3; y=4g; fx=2; y=2g; fx=3; y=2gg[[2  x = 3  y]] = ffx=3; y=2gg The other example results from the rst by an interchange of the rst and second disjunct. Now the identity statement y = x + 1 will generate a transition to , which is propagated. We get: fg[[(y = x + 1 [ 2 = y); (x = 2 [ x = 3); (2  x = 3  y)]] = fg[[y = x + 1 [ 2 = y]][[(x = 2 [ x = 3); (2  x = 3  y)]] = f; fy=2gg[[(x = 2 [ x = 3); (2  x = 3  y)]] = f; fy=2gg[[x = 2 [ x = 3]] [[2  x = 3  y]] = f; fx=2; y=2g; fx=3; y=2gg[[2  x = 3  y]] = f; fx=3; y=2gg To remedy this, we extend the states with a fourth component L, where L is a stack of literals Pt1    tn , t1 =: t2 , :Pt1    tn , :t1 =: t2 , and we replace the transition rule for Pt1    tn not -closed by the following:

Pt1    tn not a-closed t1 tn ( ; ga ; la ; L; Pt1    tn ) ( ; ga ; la; L) P ?! 

and the corresponding rule for equalities by

t1 =: t2 not a-closed and not an a-assignmnent : 1 =: t2 ( ; g a ; la ; L; t = ( ; ga ; la; L) t?! 1 t2 ) 6

Notice that the assignment rules for identity may cause the valuation to grow, which causes the need for state reduction rules such as the following:

Pt1    tn a-closed and (t 1 ; : : : ; t n ) 2 I (P ) r ( ; ga ; la; Pt1    tn ; L) ?! ( ; ga ; la; L) Pt1    tn a-closed and (t 1 ; : : : ; t n ) 2= I (P ) r ( ; ga ; la; :Pt1    tn ; L) ?! ( ; ga ; la ; L) Moreover, this reduction process can cause further increase of the valuation, in case of reductions for an identity:

t1 =: t2 an -assignment with t1  v; v ="; t 2 =#; v 2= la r ( ; ga ; la ; t1 =: t2 ; L) ?! ( [ fv=t 2 g; ga [ fvg; l ; L) For the example case above, this would give: (; ;; ;; ;)

y=: x+1

?! (; ;; ;; y =: x + 1) : x=2 ?! (fx=2g; fxg; ;; y =: x + 1) r ?! (fx=2; y=3g; fx; yg; ;; ;):

In fact, it turns out to be convenient to store slightly more information.

4 New Rules It does not always make sense to compute new values for variables. Recall that under the original execution mechanism, an assignment to a global variable would make the computation path unsafe. Now that we have a stack of unresolved literals at our disposal we could save v =: t as a constraint instead of making a global assignment to v. Since it depends on context whether v = t should be performed as a global assignments or saved on the stack as a constraint, we make a distinction between two execution modes B(uild) and C(onstrain), We will use m as a variable ranging over B; C , in the rules where the execution mode does not matter, but has to remain the same during a given transition step. Also, we will need to keep track of the set of variables used somewhere in the current stack of unresolved literals. If v is used in the stack of unresolved literals, a dynamic quanti er action 9v would destroy essential information, so we had better keep track of such situations. We will introduce a new register na for constraint variables needed by state a. A state a will now look like ( ; ga ; la; na ; La ; ma ), where

   

is a partial valuation, ga is the set of global variables, la is the set of local variables, na is the set of variables needed in a stored constraint, 7

 La is the list of literals stored as constraints,  m is either b or c, the execution mode of the state a. The use of these components of a state will be made clear as we go along introducing the transition rules. If we are in build mode, and we cannot perform an atomic test or cannot execute an equality statement (either as a test or as an assignment) due to missing values in the input, we store the predicate or equality, after substituting the values of the current state, and we add the variables that are still needed to the set of needed variables of the state. If we are in constrain mode, and we cannot perform an atomic test or execute an equality as a test statement due to missing values in the input, we do the same. Let L be de ned by the following BNF rules: Item ::= Pt1    tn j t1 =: t2 j :Pt1    tn j :t1 =: t2 L ::= [] j L; Item It will turn out useful to introduce an explicit failure state 0, for conceptual clarity. Computation of  from state a fails if all -computation paths starting from a end in 0. Compare this to the old set-up, where a computation of  from state a failed if there were no -computation paths from a. The new representation of failure will be indispensable in the rules for reducing constrained states, to express that a reduction step applied to a state a generates a failure: here we need to explicitly mark the transition to failure to ensure that no further reduction attempts will be made on a.

4.1



and 0 propagation

We still maintain an improper state  for `I don't know', and we treat it as a state of unrecoverable error. In the new set-up we make sure that we don't get there quite as easily as before. But once we are there, there is no way out. Similarly with the failure state 0. Failure is always de nite.   ?! 

 0 ?! 0

4.2 Atomic Predicate Test In case we cannot perform an atomic test due to missing values in the input, we store the set of needed variables for which no values were available, along with the predicate. If is the input valuation and Pt1    tn is the predicate, the -instance of Pt1    tn is given by Pt 1    t n , and the set of needed variables by: var (t 1 ::t n ).

Pt1    tn a-closed and (t 1 ; : : : ; t n ) 2 I (P ) t1 tn ( ; ga ; la; na ; L; ma ) ( ; ga ; la; na ; L; ma) P ?! Pt1    tn not a-closed W = var (t 1 ::t n ) P t1 tn a a a a a a a a ( ; g ; l ; n ; L; m ) ?! ( ; g ; l ; n [ W; L; Pt1    tn ; m ) 



8

Since we have an explicit representation for failure, a test that fails should occasion a transition to the failure state:

Pt1    tn a-closed and (t 1 ; : : : ; t n ) 2= I (P ) t1 tn 0 ( ; ga ; la ; na ; L; ma) P ?! 

Note that it makes no di erence whether we are in build mode or constrain mode.

4.3 Equality If an assignment to v make the valuation grow, then we have to adjust the list of needed variables (by removing v from it), and the list of constraints (by performing the substitution v=d, where d is the computed value for v). However, even if an equality t1 =: t2 is an assignment for the current valuation, we need not always perform the assignment: we will only do so when the assignment is to a local variable (dynamically bound in the current context), or to a global variable while we are in build mode. When we are in constrain mode all identities that are not tests will be put on the constraint stack. We will use L[v=d] for the result of performing substitution [v=d] to every member of L. The simplest case is the case where t1 =: t2 is a test. In this case it makes no di erence whether we are in build or constrain mode. Again, we model failure explitly by means of a transition to 0. We get:

t1 =: t2 a-closed and t 1 = t 2 1 =: t2 ( ; g a ; la ; na ; L; ma ) ( ; ga ; la ; na ; L; ma) t?! t1 =: t2 a-closed and t 1 6= t 2 1 =: t2 0 ( ; ga ; la ; na ; L; ma) t?! If t1 =: t2 is an assignment to a variable v that is local to the current context, the assignment is performed, the variable v is removed from the list of needed variables, and the relevant substitution [v=d] is performed on the stack elements. It makes no di erence whether we are in build or constrain mode:

t1 =: t2 an -assignment with t1  v; v ="; t 2 =#; v 2 la 1 =: t2 ( [ fv=t g; g a ; la ; na ? fv g; L[v=t ]; ma ) ( ; ga ; la; na ; L; ma ) t?! 2 2 : t1 = t2 an -assignment with t2  v; v ="; t 1 =#; v 2 la 1 =: t2 ( [ fv=t g; g a ; la ; na ? fv g; L[v=t ]; ma ) ( ; ga ; la; na ; L; ma ) t?! 1 1 If t1 =: t2 is an assignment to a variable v that is global to the current context, it depends on the execution mode what we will do. In build mode, we perform the assignment, remove v from the stack of needed 9

variables, and carry out the relevant substitution [v=d] on the stack elements. In constrain mode, we save the identity on the stack.

t1 =: t2 an -assignment with t1  v; v ="; t 2 =#; v 2= la 1 =: t2 ( [ fv=t g; g a [ fv g; la ; na ? fv g; L[v=t ]; b) ( ; ga ; la ; na; L; b) t?! 2 2 : t1 = t2 an -assignment with t1  v; v ="; t 2 =#; v 2= la : 1 =: t2 ( ; g a ; la ; na [ fv g; L; t = ( ; ga ; la ; na ; L; c) t?! 1 t 2 ; c) t1 =: t2 an -assignment with t2  v; v ="; t 1 =#; v 2= la 1 =: t2 ( [ fv=t g; g a [ fv g; la ; na ? fv g; L[v=t ]; b) ( ; ga ; la ; na; L; b) t?! 1 1 : t1 = t2 an -assignment with t2  v; v ="; t 1 =#; v 2= la : 1 =: t2 ( ; g a ; la ; na [ fv g; L; t = ( ; ga ; la ; na ; L; c) t?! 1 t 2 ; c) Finally, for input states where t1 =: t2 is neither an assignment nor a test, we save the identity on the stack.

t1 =: t2 not an -assignment and not -closed W = var (t 1 ; t 2 ) t1 =: t2 : a a a a a a a a ( ; g ; l ; n ; L; m ) ?! ( ; g ; l ; n [ W; L; t1 = t2 ; m )

4.4 Predicate Test Reduction For eciency reasons, we indicate the results of a reduction resulting in failure by means of a transition to 0. This prevents the futile application of other rules to the state: we make sure that there are no transitions from 0. Due to the fact that identity statements make the valuation grow, test predicates on the unresolved literal stack may turn into grounded literals (literals without variables, i.e., ;-closed literals), in which case we can perform the test. It does not matter where a test literal occurs on the stack. We indicate this with L(Pt1    tn ). In the same context, L() indicates the result of removing all occurrences of Pt1    tn from the stack L.

10

Pt1    tn grounded and (t1 ; : : : ; tn ) 2 I (P ) r a ( ; g ; la ; na; L(Pt1    tn ); ma ) ?! ( ; ga ; la; na ; L(); ma )

Pt1    tn grounded and (t1 ; : : : ; tn ) 2= I (P ) r ( ; ga ; la ; na ; L(Pt1    tn ); ma ) ?! 0 Pt1    tn grounded and (t1 ; : : : ; tn ) 2= I (P ) r a a ( ; g ; l ; na ; L(:Pt1    tn ); ma ) ?! ( ; ga ; la; na ; L(); ma ) Pt1    tn grounded and (t1 ; : : : ; tn ) 2 I (P ) r ( ; ga ; la; L(:Pt1    tn ); ma ) ?! 0

4.5 Equality Test Reduction In case an equality or inequality on the unresolved literal stack is a test for the current input, the treatment is as for stacked atomic tests.

t1 ; t2 grounded and t1 = t2 r =: t2 ); ma ) ?! ( ; ga ; la; na ; L(); ma ) t1 ; t2 grounded and t1 6= t2 r 0 ( ; ga ; la; na ; L(t1 =: t2 ); ma ) ?! t1 ; t2 grounded and t1 6= t2 r a a a ( ; ga ; la ; na ; L(); ma ) ( ; g ; l ; n ; L(:t1 =: t2 ); ma ) ?! t1 ; t2 grounded and t1 = t2 r a 0 ( ; g ; la; na ; L(:t1 =: t2 ); ma ) ?! ( ; ga ; la ; na ; L(t1

4.6 Assignment Reduction If an equality occurs anywhere in the unresolved literal stack that is an assignment for the current input, then it can be used to extend the input valuation, provided we are in build mode.

11

t1 =: t2 an -assignment with t1  v; v ="; t 2 =#; v 2 la r ( [ fv=t 2 g; ga; la ; na ? fvg; L()[v=t 2 ]; b) ( ; ga ; la ; na ; L(t1 =: t2 ); b) ?! t1 =: t2 an -assignment with t1  v; v ="; t 2 =#; v 2= la r ( [ fv=t 2 g; ga [ fvg; la; na ? fvg; L()[v=t 2 ]; b) ( ; ga ; la; na ; L(t1 =: t2 ); b) ?! t1 =: t2 an -assignment with t2  v; v ="; t 1 =#; v 2 la r ( [ fv=t 1 g; ga; la ; na ? fvg; L()[v=t 1 ]; b) ( ; ga ; la ; na ; L(t1 =: t2 ); b) ?! t1 =: t2 an -assignment with t2  v; v ="; t 1 =#; v 2= la r ( [ fv=t 1 g; ga [ fvg; la; na ? fvg; L()[v=t 1 ]; b) ( ; ga ; la; na ; L(t1 =: t2 ); b) ?!

4.7 Quanti cation If we encounter a quanti er 9v in a state with a stack L with at least one literal with v occurring in it, then we are in trouble. The bookkeeping device for the set of needed variables for stack reduction is na . In case v 2 na , there is nothing we can do but go to the state of irrecoverable error. The reason is that there is an unresolved test involving v on the stack, and that test cannot be postponed any further.

v 2 na v ( ; ga ; la ; na ; L; ma) ?!  9

If 9v is executed in a state ( ; ga ; la; na ; L; ma) where v is not in the domain of , and moreover, none of the literals L needs v, we merely have to put v in the local variable register, to mark it as local in the current context.

v 2= dom ( ); v 2= na v ( ; ga ; la ; na ; L; ma) ?! ( ; ga ; la [ fvg; na ; L; ma) 9

If 9v is executed in a state ( ; ga ; la ; na; L; ma ) where v is in the domain of , but none of the literals in L needs v, we throw away the old -value of v, and put v in the local variable register.

v 2 dom ( ); v 2= na v ( ; ga ; la ; na ; L; ma) ?! ( ? fv=v g; ga ; la [ fvg; na; L; ma ) 9

12

4.8 Negation As the treatment of negation is rather involved, some preliminary de nitions are useful. Here is a de nition of a reduced computation.   r a?! r b : either a?!b and there is no b with b?!b  r r r    ?! b; and there is no b with b?! b: or a?! a1?! 0

0

0

0

We de ne a by means of: 

( ; ga ; la ; na ; L; ma) := ( ; dom ( ); ;; na ; L; c): 

In other words, a denotes the result of putting the list of global variables of a equal to the domain of the valuation, making the list of local variables of a empty, and putting the state in constrain mode. 

 In terms of ?! r we de ne the set of all outcomes of computations  starting from a , as follows: 

 Oa () := fb j a ?! r bg: 

In other words, Oa () is the set of all fully reduced output states that are the result of executing  in state a . Next, note that if we take care to always execute formulas in the scope of negation in constrain mode (this is part of the de nition of a ), no global assignment ever takes place (as is easily veri ed by inspection of the rules). In constrain mode, instead of assigning a new value to a global variable v, we put a constraint on v on the stack. In other words, the members b of Oa () will all be safe, in the sense that they all will satisfy gb = dom ( ). The members of Oa () fall in the following categories: 



   

b is simple if b has the form ( ; gb ; lb; ;; ;; c). An imple state is one with an empty stack of literals. b is constrained if b has the form ( ; gb ; lb; na; L; c), with na 6= ;, L 6= ;. b = 0: the failed state. b = : the don't know state.

In cases where the set of outcomes Oa () contains at least one simple state, we know that the embedded computation has succeeded, so the computation of : from a should fail (we should get an explicit transition to 0):

b 2 Oa() with b simple. a ?! 0 :

If Oa () = f0g, we know that the embedded computation has failed, so the computation of : from a should succeed:

13

Oa () = f0g

a ?! a :

If the set Oa () ?f0g is non-empty and contains only constrained states, we can dualize it. If l is an atom or identity A, then l is its negation :A; if l is a negated atom or identity :A, then l is the unnegated literal A. We call l the converse of l. D(L1 ; : : : ; Ln ) := f(l1 ;    ; ln ) j lj 2 Lj for 1  j  ng: In other words, the set D(L1 ; : : : ; Ln ) consists of all the strings of literals that result from picking one literal from each of L1; : : : ; Ln and taking its converse. E.g., if L1 = (Px; Rxy) and L2 = (Qx; :Sxz ), then

D(L1 ; L2 ) = f(:Px; :Qx); (:Px; Sxy); (:Rxy; :Qx); (:Rxy; Sxy)g: If L is a list of literals, var (L) is its list of needed variables. If L and L are lists of literals, L + L is the result of merging these lists. We now lift the dualisation operation to the level of sets of states; assume that a has the form ( ; ga ; la; na ; La ; ma): 0

0

Da(b1 ; : : : ; bn ) := f( ; ga ; la ; na [ var (L ); La + L ; ma ) j L 2 D(Lb1 ; : : : ; Lbn )g: 0

0

0

The next rule uses dualisation to compute appropriate dualized stacks of literals.

B = Oa() ? f0g 6= ;; all members of B constrained; b 2 Da(B) a ?! b :

Finally, we need a rule to specify the cases where the negation cannot be correctly computed. This happens when  2 Oa (), while Oa () does not contain any simple states. No b 2 B = Oa () simple;  2 B

a ?!  :

4.9 Composition, Union, Bounded Search/Choice Nothing out of the ordinary here. Using a; b; c as shorthand for ( ; ga ; la; na ; La ; ma ) etc, we get:

14

1 2 a ?! b b ?! c 1 ;2 a ?! c i a ?! b i 2 f1; 2g 1 2 a ?! b  N a ?! b b ?! c 0 N +1 a ?! a a ?! c [

t ( ; ga ; la; na ; La ; ma ) ?!



v [ ::t  1 2 ( ; ga ; la ; na ; La; ma ) t?!



N

 ( ; ga ; la ; na ; La; ma ) ?! b t =N t  ( ; ga ; la ; na ; La; ma ) ?! b t 2 =" v t1 ::t2  a a a a a ( ; g ; l ; n ; L ; m ) ?! 

t =" t 1 ="

[

=j; b ( ; ga ; la ; na; La ; ma ) v?!

v [ ::t  1 2 ( ; ga ; la; na ; La ; ma ) t?!

b

t 1 = M; t 2 = N; M  j  N

5 Ways of Running the Dynamo Execution Process It is convenient to de ne the outcome of a Dynamo computation process as a set of reduced states. Let a valuation be given. Then the state based on is the state s given by: ( ; dom ( ); ;; ;; ;; b): The result of running  from state s is given by:  r a?! bg: Rs () := fb j 9a such that s ?!

In other words, the result will not contain states with grounded literals on their constraint stacks, for r such grounded literals represent tests that can be applied, and they will be applied during the ?! steps. In addition, it may be useful to check the constraint lists for consistency, by means of applying a rule like the following:

l 2 L ^ l 2 L

r ( ; ga ; la ; na ; L; ma) ?!

0

As a special case, we have execution from the state of minimal information s = (;; ;; ;; ;; ;; b). Also special is the case where Dynamo execution starts out from a test state for , i.e., from an initial valuation with var ()  dom ( ), where var () is the list of variables that occur dynamically free in ;

15

. One should be able to prove that if execution starts out from a test state for  the states that result

from the execution will not be constrained. A nal possibility that should be noted here is execution of  from an initial state that imposes a list of constraints L, say with valuation : ( ; dom ( ); ;; var (L ); L ; b): This can be useful for putting initial constraints on computed solution sets.

6 Further Work A prototype implementation of Dynamo is described in [4]. The Dynamo language demonstrates that dynamic interpretation of FOL can be used as guideline for dynamic logic programming. Dynamo programs have a purely declarative dynamic semantics. There are no side e ects, and no control features: Dynamo is pure dynamic logic. Further work on the agenda includes the following tasks:

Analyse Improved Execution Mechanism Prove faithfulness to dynamic interpretation of FOL of

the extended execution mechanism. Update Implementation Incorporate the extended execution mechanism in the implementation. Further Improvement of Implementation Extend Dynamo with a typing system, and with a mechanism for decidable subrecursion. Integration Extend Dynamo with helpful returns upon defeat, to be used in an integration of Dynamo with other inference engines for rst order logic. Application Put Dynamo to the practical test in promising domains like Boolean constraint satisfaction, NL parsing, parallel search algorithms, relational database query. Theory Put Dynamo to theoretical use in the construction of decision machines for fragments of rst order and higher order logic.

References [1] Krzysztof Apt, Jacob Brunekreef, Vincent Parrington, and Andrea Schaerf. Alma-0: An imperative language that supports declarative programming. Technical Report PNA-R9713, CWI, 1997. [2] J. Barwise. Noun phrases, generalized quanti ers and anaphora. In P. Gardenfors, editor, Generalized Quanti ers: linguistic and logical approaches, pages 1{30. Reidel, Dordrecht, 1987. [3] Jan van Eijck. Computing with dynamic predicate logic. Manuscript, CWI/ILLC, January 1999, Available from www.cwi.nl/~jve/dynamo. [4] Jan van Eijck. Dynamo | a language for dynamic logic programming. Manuscript, CWI/ILLC, December 1998. Available from www.cwi.nl/~jve/dynamo. [5] Jan van Eijck. Programming with dynamic predicate logic. Technical Report CT-1998-06, ILLC, 1998. Available from www.cwi.nl/~jve/dynamo. [6] J. Groenendijk and M. Stokhof. Dynamic predicate logic. Linguistics and Philosophy, 14:39{100, 1991. 16