Page 1

Modeling Systems in CLP with Coinductive Tabling

JOXAN JAFFAR, ANDREW E. SANTOSA, AND R˘ AZVAN VOICU

School of Computing

National University of Singapore

{joxan,andrews,razvan}@comp.nus.edu.sg

Abstract. We present a methodology for the modelling of complex program be-

havior in CLP. The first part of this paper is an informal description about how

to represent a system in CLP. At its basic level, this representation captures the

precise trace semantics of concurrent programs, or even high-level specifications,

in the form of a predicate transformer. Based on traces, the method can also cap-

ture properties of the underlying runtime system such as the scheduler and the

microarchitecture, so as to provide a foundation for reasoning about resources

such as time and space.

The second part of this paper presents a formal and compositional proof

method for reasoning about safety properties of the underlying system. The idea

is that a safety property is simply a CLP goal, and is proof established by exe-

cuting the goal by a CLP interpreter. However, a traditional CLP interpreter does

not suffice. We thus introduce a technique of coinductive tabling to CLP. Essen-

tially, this extends CLP so that it can inductively use proof obligations that are

assumed but not yet proven, and it can generate new proof obligations assertions

dynamically.

1Introduction

Constraint Logic Programming (CLP) [11] has been successful as a framework for

executable specifi cations, and several CLP systems have been successfully deployed

widely in application areas such as artifi cial intelligence and combinatorial optimiza-

tion (see eg. [14]). Its competitive advantage is expressive power coupled with a pow-

erful inference method. In this paper, we present a systematic application of CLP to

reasoning about complex program behavior.

We start with an informal but broad coverage of how to model various aspects of

the operation semantics of programs. Starting with the basic concepts of strongest-

postcondition and weakest-precondition, we then consider sequential and concurrent

systems, including perpetual processes, and various synchronization mechanisms. Our

modeling of these operational concepts is exact in the sense that the trace semantics of

the underlying program is represented in the CLP model. Going further, we show how

also to model the machine in which the program executes, focusing in particular, on the

scheduler for nondeterministic actions (such as the choice of which process to execute

next) and on the microarchitecture, which is often critical in determining the cost of

execution. We thus cover reasoning not only about the values of program variables, but

alsoaboutresources.At theendofthissection,weshowthata safetyproofofa program

Page 2

is established by executinga particulargoal against the CLP modelof the program,thus

providing a generic and compositional methodology for program reasoning with CLP.

However, basic CLP is not quite suffi cient for this purpose.

The second part of this paper contains the main technical contribution: extending

basic CLP with coinductive tabling. Essentially, this extends CLP so that it can induc-

tively use proof obligations that are assumed but not yet proven, and it can generate

new proof obligations assertions dynamically. This technique is akin to the notion of

tabling in logic programming systems (see eg. [18]) in that the main purpose is to ob-

tain termination when dealing with recursion. In standard tabling, procedure calls and

their answers are tabled so as not to repeatthem. In our tabling,the main differencesare

fi rst that the setting is CLP and not just logic programming, and more importantly, that

proof obligationsand notjust calls are tabled.(We donot table answers.)Terminationis

obtained by applying a principle of coinduction (see eg: Appendix B of [15]), that is: a

recursiveproofobligationmaybe provedby assuming that a precedingproofobligation

is true.

Finally, we briefly discuss some important extensions that are not covered in this

paper. The most important extension concerns the use of abstraction, in the manner

of abstract interpretation [4]. We shall just explain that our proof method may be aug-

mented by a liberally applying a notion of abstraction to a goal in a proof, preserving

correctness. The advantage of abstraction is, of course, to enhance the process of ter-

mination. Another important extension is to deal with liveness or progress. Here, we

discuss briefly how to include a notion of well-founded induction. Finally, we mention

how to deal with an unboundednumber of processes, ie: parameterized systems.

1.1Related Work on CLP and Program Reasoning

There has been some recent work on using logic programs to describe concurrent pro-

grams, and which employ a systematic algorithm. Work based on the XSB and XMC

systems [17] used assertions based on the µ-calculus and executed the logic program

representations of programs and assertions using a tabling mechanism. Delzanno and

Podelski [6] showed that a transition system and its CTL-based verifi cation conditions

can be translated into a CLP program in way that the symbolic CLP fi xpoint opera-

tions can be used in the proof process. There are other works using CLP to describe

program behavior, eg. that by Flanagan [8] for imperative programs, and that by Gupta

and Pontelli [9] for timed automata, but these do not describe a systematic CLP-based

algorithm.

2CLP Preliminaries

We fi rst briefly overview CLP [11]. The universe of discourse is a set of terms, inte-

gers, and arrays of integers. A constraint is written using a language of functions and

relations. They are used in two ways, in the base programminglanguageto describe ex-

pressions and conditionals, and in user assertions, defi ned below. In this paper, we will

not defi ne the constraint language explicitly, but invent them on demand in accordance

Page 3

with our examples. Thus the terms of our CLP programs include the function symbols

of the constraint language.

An atom, is as usual, of the form p(˜ t) where p is a user-defi ned predicate symbol

and the ˜ t a tuple of terms. A rule is of the form A:-˜B,φ where the atom A is the head

of the rule, and the sequence of atoms˜B and the constraint φ constitute the body of the

rule. A goal G has exactly the same format as the body of a rule. We say that a rule is

a (constrained) fact if˜B is the empty sequence. A ground instance of a constraint, atom

and rule is defi ned in the obvious way.

Let G = (B1,··· ,Bn,φ) and P denote a goal and program respectively. Let R =

A:-C1,··· ,Cm,φ1denote a rule in P, written so that none of its variables appear in

G. Let A = B, where A and B are atoms, be shorthand for equations between their

corresponding arguments. A reduct of G using R is of the form

(B1,··· ,Bi−1,C1,··· ,Cm,Bi+1,··· ,Bn,Bi= A∧φ∧φ1)

provided Bi= A∧φ∧φ1is satisfi able.

A derivation sequence is a possibly infi nite sequence of goals G0,G1,··· where

Gi,i > 0 is a reduct of Gi−1. If there is a last goal Gnwith no atoms, notationally (?,φ)

and called a terminal goal, we say that the derivation is successful and that the answer

constraint is φ. A derivation is ground if every reduction therein is ground.

In what follows, we shall only be concerned with goals that contain at most one

atom. Thus the reduct of a goal is deterministic on the rule that is employed.

Definition 1 (Unfold). Given a program P and a goal G which contains one atom.

Then unfold(G) is the set of reducts obtainedby using all the rules. An unfoldoperation

on G results in a subset of unfold(G); we say the operation is complete if it returns

all of unfold(G). An unfold tree of G (sometimes also called a proof tree) is a tree of

goals obtainedby successively applyingunfold operationson G, and then on the results

of the previous operation, etc. We say that the unfold tree is complete if all the unfold

operations used in its construction were complete1.

3 Modeling in CLP

We start by modeling the program P with variables˜X as a predicate transformer [7]

by fi rst identifying target variables˜Xtcorrespondingto˜X, and then establishing a con-

straint on˜X and˜Xt.

3.1The Logical Basis of CLP Modeling

To outline the predicate transformer aspect of a (possibly nondeterministic) program,

weexpressitssemanticsasasetofCLPclausesthatdefi nethepredicatestate(PP,˜X,˜Xt),

where the logic variables˜X and˜Xtrepresent values of program variables at program

point PP, and at a target program point, respectively. The state predicate realizes the

followingrelation: if˜X are values of variablesat programpointPP, then˜Xtare possible

values of the program variables at the target program point. There are two alternatives

1Thus a complete tree is not necessarily one where unfold operations have been exhaustively

performed; rather, it is where each unfold operation used was complete.

Page 4

forimplementingsuch a relation:bottomup, usingstrongestpostconditionpropagation,

and top-down,using weakest preconditionpropagation.We introducethese conceptsby

example.

Consider the simple program <0> x := x + 1 <1> where 0 denotes the entry

point and 1 denotes the exit point. The bottom-up CLP model of this program is:

state(0, X, Xt) :- state(1, X + 1, Xt).

state(1, X, X).

Runningagoalsuchas ?- state(0, X, Xt), X > 5,wouldreturnXt > 6,thestrongest

postcondition of P when run with input x > 5. Similarly, the top-down CLP model:

state(1, X, Xt) :- state(0, X - 1, Xt).

state(0, X, X).

capturestheweakestpreconditionofP.Running ?- state(1, X, Xt), X > 5,would

return Xt > 4.

This simple idea is reminiscent of Hoare-like specifi cations of programs, such as

{x > 5} x := x + 1 {x > 6} or {x > 4} x := x + 1 {x > 5}, using the above

examples. However, our approach is more powerful, in the sense that it can represent

properties of nonterminating programs. Consider for example the program <0> while

(true) x := x + 1 <1> endwhile <2> where the program points 0, 1 and 2 are

displayed. The bottom-up CLP model:

state(0, X, Xt) :- state(1, X + 1, Xt).

state(1, X, Xt) :- state(1, X + 1, Xt).

state(1, X, X).

captures in Xt all the values of X that can appear at program point 1. That is, the goal

?- state(0, X, Xt), X > 5, for example, has as solutions: Xt > N for all N > 6.

Figure 1 shows a while program and both its top-down and bottom-up CLP mod-

els. The target program points are 3, for the bottom-up model, and 0 for the top-down

model.We notethatfortop-downmodels,targetvariablesare requiredonlybythecom-

positional nature of our modeling. While this is an important feature, it is not the topic

of interest in many of our examples; thus, for clarity, we remove the target variables

from such examples.

We note that we could enhance the CLP model of a program such that the target

program point become a parameter of the state predicate. The major benefi t of this

approach is that the CLP model of the program at hand allows queries on multiple

target program points. Moreover, it is rather obvious that such a CLP model could be

automatically derived for any program. While this approach is of practical importance,

and has a straightforward implementation, it would unnecessarily complicate our ex-

amples. To illustrate our points, we shall rather use specialized, manually derived CLP

models in our examples.

3.2Concurrency

Consider our next example user program shown in Figure 2, a two-process Bakery mu-

tual exclusion algorithm. Note that the point ?2? indicates the critical section. Initially,

t1= t2= 0. The CLP model is shown in Figure 3. Note that we now use a pair of pro-

gram points, instead of just one. Note also that we consider “blocking” concurrency

Page 5

?0? while (i < n) do

?1?

?2? end ?3?

i := i + 1

Top-Down Model

state(0,I,N,I,N) :- I=0, N≥0.

state(1,I,N,It,Nt) :- I<N, state(0,I,N,It,Nt).

state(1,I,N,It,Nt) :- I<N, state(2,I,N,It,Nt).

state(2,I+1,N,It,Nt) :- state(1,I,N,It,Nt).

state(3,I,N,It,Nt) :- I≥N, state(0,I,N,It,Nt).

state(3,I,N,It,Nt) :- I≥N, state(2,I,N,It,Nt).

Bottom-Up Model

state(0,I,N,It,Nt) :- I≥N, state(3,I,N,It,Nt).

state(0,I,N,It,Nt) :- I<N, state(1,I,N,It,Nt).

state(1,I,N,It,Nt) :- state(2,I+1,N,It,Nt).

state(2,I,N,It,Nt) :- I<N, state(3,I,N,It,Nt).

state(2,I,N,It,Nt) :- I≥N, state(3,I,N,It,Nt).

state(3,I,N,I,N).

Fig.1. Simple While Program

while (true) do

t1 := t2 + 1

await (t1<t2 ∨ t2=0)

t1 := 0

end

?0?

?1?

?2?

while (true) do

t2 := t1 + 1

await (t2<t1 ∨ t1=0)

t2 := 0

end

?0?

?1?

?2?

Fig.2. Bakery-2

here, that is, we have an “await” statement, which is modelled to block until the speci-

fi ed condition holds. The safety property of interest, mutual exclusion, can be obtained

by proving that ?- state([2,2], T1, T2) has no solutions.

In this example, we adopted an asynchronous composition (instructions interleav-

ing) of processes. Our frameworkis also flexible enoughto model synchronouscompo-

sition, as exemplifi ed in [13]. It is also possible to replace the awaits with busy loops,

obtaining non-blocking concurrent programs.

3.3High-Level Specifications

Consider a timed automaton [1] in Figure 4 describing a daily schedule of a worker. In

this example,the variabley is nota clock,buta simplecontinuous(realorrational)vari-

able. Constraints involving both clocks and dynamically changing variables, as shown,

cannot be handled by current timed automata model checkers. This is because the stan-

dard algorithms depend on an analysis of clock regions, which use a more restrictive

class of real constraints. Here, we may query if a worker can be out of the house for

more than 20 hours, for example, by showing that ?- state(0,X,Y,Z) implies Y ≤

20.

We show our top-down CLP model in Figure 5. See [13] for more details and ex-

amples of CLP modeling of timed automata.