Chronolog(Z): Linear-time Logic Programming∗
Mehmet A. Orgun
William W. Wadge
Weichang Du
Abstract
This paper introduces Chronolog(Z), a logic programming language based on a discrete
linear-time temporal logic with unbounded past and future. Chronolog(Z) is suitable for
applications involving the notion of dynamic change, such as modeling non-terminating computations, the simulation of sequential circuits, and temporal databases. The execution of
the programs of the language is based on a resolution-type proof procedure called TiSLDresolution. A modular extension of Chronolog(Z) is proposed which can be used to model
objects with internal memory.
1
Introduction
Temporal logic has been successfully used as a formalism in concurrent program specification and
verification, modeling temporal databases, and various forms of temporal reasoning. In temporal
logic [15], the meanings of formulas vary depending on an implicit time parameter and elements
from different moments in time can be combined through the use of temporal operators, not by
explicit references to time. More recently, a number of logic programming languages based on
diverse temporal logics have been proposed: Tempura [12] and Tokio [2] are based on interval
logic; Templog [1] and Chronolog [13] are based on linear-time temporal logics and Temporal
Prolog [9] is based on linear and branching-time temporal logics.
In Tempura, programs are systematically transformed into a sequence of state descriptions
over an interval that satisfies the original program [12]. Templog [1], Temporal Prolog [9] and
Chronolog [13] are extensions of logic programming in which temporal logic programs are executed
to obtain answers by the use of resolution-type proof procedures. Tokio has a mixed execution
mechanism [2].
There are also several attempts at developing semantics of temporal logic languages. Baudinet
showed [3] that Templog’s proof procedure is sound and complete; and established the equivalence of the declarative and the operational semantics of Templog programs. Orgun and Wadge
provided [13, 14] the semantics of Chronolog programs and outlined a complete proof procedure
for the language. Gabbay [10] defined a resolution procedure for Temporal Prolog and proved its
soundness. These results suggest that temporal logic programming is feasible.
This paper in particular introduces the temporal language Chronolog(Z), which is an extension
of Chronolog [13], based on a linear-time temporal logic with unbounded past and future with
the set Z of integers as the collection of moments in time. The temporal logic of Chronolog(Z)
has an operator to look into the past as well as the operators first and next of Chronolog.
The “execution” of Chronolog(Z) programs is based on a resolution-type proof procedure called
TiSLD-resolution. In [14], it is also known that the declarative and the operational semantics of
Chronolog(Z) programs coincide.
Consider the following program that defines the predicate f which is true of the (t + 1)-st
∗ Published in Osman Abou-Rabia, Carl K. Chang, Waldemar W. Koczkodaj, editors, Computing and Information (ICCI’93 ), IEEE Computer Society, pp.545–549, 1993.
1
Fibonacci number for time t ≥ 0 and no other.
first f (1).
first next f (1).
next next f (N ) ← next f (X), f (Y ), N is X + Y.
Read all clauses as assertions true at all moments in time. The first two clauses define the first
two Fibonacci numbers as 1; and the last clause defines the current Fibonacci number as the sum
of the previous two. For example, the answer to the given goal ← first next next f (X) is a
(substitution) instance of the goal with X replaced by 2.
In the following, we first outline the temporal logic of Chronolog(Z). We then discuss several
applications of the language, including modeling non-terminating computations and the simulation
of sequential circuits. We also propose a modular extension of Chronolog(Z) for specifying objects
with internal memory.
2
Temporal Logic of Chronolog(Z)
In the temporal logic of Chronolog(Z), the collection of moments in time is the set Z of integers. The temporal logic offers three temporal operators: first, prev and next. Informally, the
temporal operators refer to the initial moment, the previous moment and the next moment in
time, respectively. We choose a linear-time temporal logic with unbounded past and future as
the underlying logic of Chronolog(Z), because certain time-dependent properties are more natural
and easier to express with past operators and the symmetry between past and future operators is
best expressed in such a temporal logic.
The syntax of the temporal logic of Chronolog(Z) extends that of first-order logic with three
new formation rules: if A is a formula, so are first A, prev A and next A. We write next(n)
and prev(n) for n successive applications of next and prev, respectively. From here on, we refer
to the underlying logic as TL.
2.1
Temporal Interpretations
The semantics of formulas of TL are provided by temporal interpretations. A temporal interpretation of TL assigns meanings at all moments in time to all basic elements of the language,
such as function and predicate symbols, and variables. Intepretations are extended upward to all
terms and formulas of TL by a satisfaction relation |=. The meaning of a formula of TL varies in
time. However, we restrict the discussion to those temporal interpretations in which the values of
variables and function symbols are “rigid”. The value of a rigid term is an invariant of time.
We assume a standard definition of the satisfaction relation |= in terms of temporal interpretations. In the following, the fact that a formula A is true at a moment t in time in a temporal
interpretation I is denoted as |=I,t A. The formal semantics of temporal operators of TL are given
as follows:
• |=I,t first A iff |=I,0 A.
• |=I,t prev A iff |=I,t−1 A.
• |=I,t next A iff |=I,t+1 A.
where A is a formula, and t ∈ Z.
If a formula A is true in a temporal interpretation I at all moments in time, we say that A is
true in I, or I is a model of A, and denote this fact as |=I A. We regard ¬, ∧ and ∀ as primitives
and assume the usual definitions of ∨, →, ↔ and ∃ in terms of these primitives.
2
2.2
Axioms of Temporal Logic
Let the notation ⊢ A denote the fact that A is a theorem of TL. The notion of deducibility can be
characterized in terms of theoremhood: Γ ⊢ A means that the formula A is deducible from a set Γ
of formulas in TL. The following axioms state some of the important properties of the temporal
operators. Let ∇ stand for any of first, prev and next.
1. Temporal operator cancellation rules.
E1. ∇(first A) ↔ first A.
E2. next prev A ↔ A.
E3. prev next A ↔ A.
The first axiom (E1) states that the initial truths persist. The axioms E2 and E3 capture
the fact that prev and next are complete inverses.
2. Temporal operator distribution rules.
D1. ∇(A ∧ B) ↔ (∇A) ∧ (∇B).
D2. ∇(¬A) ↔ ¬(∇A).
These axioms state that the temporal operators commute with ∧ and ¬.
3. Rigidness of variables.
V. ∇(∀x)(A) ↔ (∀x)(∇A).
This axiom stipulates that the values of individual variables range over extensions (data
values).
4. Rules of inference: we have the following temporal-operator introduction rules.
R1. If ⊢ A, then ⊢ first A.
R2. If ⊢ A, then ⊢ prev A.
R3. If ⊢ A, then ⊢ next A.
It is straightforward to show the correctness of the axioms and the rules of inference (that is, the
soundness of the axiomatic system).
Lemma 1 ([14]). All of the axioms and the rules of inference are valid with respect to the semantics
scheme of TL.
We assume that the rules of inference given above are extended to consider the notion of
deducibility from a set of formulas. The resolution-type proof procedure of Chronolog(Z) is based
on these axioms and rules of inference [14].
2.3
Temporal Logic Programs
In programs of Chronolog(Z) such as the Fibonacci program given earlier, program clauses can
contain applications of temporal operators to atomic formulas. We call atomic formulas with a
number (possibly 0) of applications of temporal operators as temporal atoms. All variables in
program clauses are assumed to be universally quantified. For convenience, we use upper-case
letters for variables and lower-case letters for function and predicate symbols. A temporal logic
program of Chronolog(Z) is the conjunction of a set of program clauses regarded as assertions
true at all moments in time. Programs of Chronolog(Z) are executed using a resolution-type proof
procedure called TiSLD-resolution [14].
3
We need the notion of a canonical formula: Given a formula A, by systematic applications of
R1, R2 and R3, the following initial truths can be formed:
(by R1),
first A
(by R2, R1),
(by R3, R1),
first prev A
first next A
first prev prev A
(by R2, R2, R1),
first next next A
(by R3, R3, R1),
and so on. Initial truths obtained from a formula A in the above fashion are called initial instances
of A.
As the following lemma states, the value of a given formula in a temporal interpretation can
be expressed in terms of the values of its canonical instances.
Lemma 2 ([14]). Let A be a formula and I a temporal interpretation of TL. |=I A if and only if
|=I At for all canonical instances At of A.
TiSLD-resolution is applied to a set of canonical program and goal clauses. We assume that,
in canonical instances of program clauses, all superfluous applications of temporal operators are
eliminated by axioms E1–E3. For a given temporal logic program, canonical instances of program
clauses are obtained by rules R1–R3 and axioms D1 and D2. When the canonicality restriction
is lifted for goal clauses, they can be open-ended. Open-ended goal clauses are used to initiate
non-terminating computations (see below). Note that a thorough exposition to TiSLD-resolution
can be found in [14].
3
3.1
Applications
Non-terminating Computations
In temporal logic programming, non-terminating computations can be modeled by time-varying
predicates. Consider Hamming numbers, which are multiples of 2, 3 and 5 of the form
2i 3j 5k for some i, j and k.
We write a Chronolog(Z) program to produce the sequence of Hamming numbers in increasing
order without any repetitions. In the program, the hamming predicate is true of the (t+1)-st
Hamming number at time t ≥ 0 and no other.
hamming(X) ← residue [X | L] .
first residue [1] .
residue(L1 ) ←
prev residue [X | L] ,
multiply(2, X, X2 ), multiply(3, X, X3 ),
multiply(5, X, X5 ), merge [X2 , X3 , X5 ], L, L1 .
merge(L1 , L2 , L3 ) ← · · ·
multiply(X, Y, Z) ← · · ·
We assume a standard definition for merge in which two given ordered lists are merged to produce a
third ordered list with duplicates removed. The residue duplicate hols all those Hamming numbers
produced but not yet consumed by the hamming predicate. In the program, the hamming predicate
is specified for the non-negative part of the linear time.
4
According to the program, the residue predicate is true of the residue list [1] at time 0, which
means that, by the first clause, 1 is the first Hamming number. At time 1, by the third clause,
1 is removed from the residue list and then multiples of 1 are merged with the rest of the residue
list (the empty list [ ]). Thus the residue predicate represents the residue list [2, 3, 5] at time 1,
meaning that the second Hamming number is 2. At time 2, by the third clause, 2 is removed
from the residue list and multiples of 2 are merged with the rest of the residue list (the list [3, 5]).
The residue predicate represents the residue list [3, 4, 5, 6, 10] at time 2, meaning that the third
Hamming number is 3. The computation proceeds along these lines.
The open-ended goal clause ← hamming(N ) triggers a non-terminating computation of Hamming numbers. The goal is interpreted as an infinite series of canonical subgoals into the future
of the form first hamming(N ), ← first next hamming(N ), ← first next(2) hamming(N ),
and so forth. The answers to canonical subgoals obtained by TiSLD-resolution in fact constitute
the answers to the original goal [14]. The sequence of answer substitutions for N represents the
sequence of Hamming numbers.
An implementation of Chronolog(Z) produces answers to canonical subgoals as long as time
and resources permit. The starting point and direction of the computation may be determined by
users or detected automatically by the implementation. The hamming predicate depends on the
residue predicate; the residue predicate is defined by an initial clause and a program clause with
recursive past dependencies. Therefore, a non-terminating computation in the negative direction
cannot produce any results.
3.2
Circuit Simulation
Clocksin [5] outlined a logic programming method for specifying and reasoning about sequential
circuits. A sequential circuit contains memory elements, such as flip-flops, and the next state of
the circuit is a function of its current state plus its inputs. We now write a Chronolog(Z) program
to simulate a synchronous 3-bit counter (see Figure 1). The counter consists of two “and” gates
and three JK flip-flops. In the counter, JK inputs are connected to logic high.
Q3
J
Ck
Q
✏ J
Ck
✑
K
r
K
input
r
Q1
Q2
Q
r
✏ J
Ck
✑
K
Q
r
Figure 1: A synchronous 3-bit counter
In circuit specifications, a circuit unit with n ports can be represented by an n-ary predicate
specifying the behavior of the unit. In the synchronous 3-bit counter circuit, there are two primitive
units, that is, an “and” gate and a JK flip-flop. The and (In 1 , In 2 , Out) predicate specifies the truth
table of an “and” gate with two input ports In 1 and In 2 and an output port Out; for example,
and (0, 1, 0) holds where the constants 0 and 1 stand for logic low and logic high, respectively.
The jk (J, K, Ck , Q, Qnext) predicate specifies a clocked JK flip-flop with J-input J, K-input K,
clock input Ck , output Q and the next state Qnext. We have left out the negated Q output and
S and R inputs, usually available in JK flip-flops, to simply the specification. We now give the
5
definition of the jk predicate:
jk (0, 0, 1, Q, Q).
jk (0, 1, 1, Q, 0).
jk (1, 0, 1, Q, 1).
jk (1, 1, 1, 0, 1).
jk (1, 1, 1, 1, 0).
jk ( , , 0, Q, Q).
In Chronolog(Z), the frequency of the clock can be defined by making the use of the linear
time of the logic. For instance, the program clause clock (1) specifies a clock synchronized with
Chronolog(Z) time under the assumption that the clock signal is high when it is sampled at each
moment in time, but it is low between any two consecutive moments in time. In the specification
of the counter circuit, the input to the circuit is taken from the clock predicate. The following is
the definition of the counter predicate:
first counter (0, 0, 0).
next counter (Q1 , Q2 , Q3 ) ←
clock (Ck ), counter (I1 , I2 , I3 ),
jk (1, 1, Ck , I3 , Q3 ), and (Ck , I3 , C3 ),
jk (1, 1, C3 , I2 , Q2 ), and (Ck , I3 , T ),
and (T, I2 , C2 ), jk (1, 1, C2 , I1 , Q1 ).
The first clause states that the counter is reset at the initial moment in time. The second clause
specifies the behavior of the circuit in terms of its current values and the clocked input. Shared
variables represent connections among the units in the circuit. In the second clause, two and
units are used to model an and unit with three inputs. As in the Hamming-numbers example, the
open-ended goal ← counter (X, Y, Z) starts a non-terminating computation.
The temporal-logic-programming approach to circuit simulation has the advantages of the
logic-programming method of Clocksin [5]. It supports modularity and circuit specifications are
directly executable by Chronolog(Z) implementations. Since it is based on a linear-time temporal
logic, it also offers additional advantages: feedback loops can be more naturally specified, and
delays and timing requirements can be modified in a rigorous manner.
3.3
Temporal Deductive Databases
We now consider a subset of Chronolog without any function symbols, that is Temporal Datalog.
Programs or Temporal Datalog can be regarded as “temporal deductive databases”. The meaning
of a Temporal Datalog program is considered as the temporal database the program models intensionally, in which each predicate in the program represents a temporal relation. Slices of temporal
relations are finite at particular moments in time or over periods of time, owing to the restriction
to the function-free subset of logic programs, but they are infinite in the aggregate.
Consider a simple database for a library. Suppose that new books do not go into circulation
until two weeks after their arrival. After then, they stay in circulation on a daily basis. Here the
logical time is interpreted as days. Let the inCirc predicate represent all those books that are in
circulation. The following is the partial definition of inCirc.
first inCirc(mobyDick ).
first inCirc(lesMiserables).
first inCirc(theHobbit).
...
next(14) inCirc(Book ) ← newArrival (Book ).
next inCirc(Book ) ← inCirc(Book ).
6
The first three rules define the books mobyDick , lesMiserables and theHobbit to be in circulation on
the first day (time 0). The last two rules formalize our assumptions about the books in circulation.
Note that the newArrival predicate is not formalized in the program, but supplied as input.
Bottom-up evaluation strategies, such as fixed-point computation, are used to compute the
meaning of a given Datalog program [4]. In Temporal Datalog, only slices (finite portions) of temporal relations represented by time-varying predicates can be computed by bottom-up evaluation
strategies.
3.4
Modular Chronolog(Z)
In a modular extension of Chronolog(Z), we can specify software modules with internal memory.
The extension is based on Fitting’s proposal [8] for modular logic programming. As an example,
we give the specification of a stack module with unlimited capacity [13]. The actions on the stack
are controlled by supplying a sequence of commands through the cmd predicate. Items are added
to the stack with push commands and the top item is removed with pop commands. We assume
that at any moment in time, exactly one action is allowed: we can push an item onto the stack
or remove the top item. The pop command has no effect if the stack is empty. The output of the
module is the top predicate, which is true of the item on top of the stack (if there is one) at any
given moment in time.
module mod :
import cmd ; export top.
first stack [ ] .
next stack [X | S] ← cmd push(X) , stack (S).
next stack (S) ← cmd (pop), stack [X | S] .
next stack [ ] ← cmd (pop), stack [ ] .
top(X) ← stack [X | S] .
end.
The first clause states that the stack is initially empty. The next three clauses specify the next
state of the stack, depending on its current state and the action indicated by cmd . The last
clause specifies the output predicate top. The stack predicate models the internal memory for the
module, which is not observable from the outside world. Thus the notion of a “state” is captured
within the module.
4
Conclusions
We have introduced the temporal logic language Chronolog(Z) and outlined its features. Other
applications of non-classical logics to logic programming include the multidimensional language
Intense [11] and the modal framework Molog [6]. For more details on temporal and modal logic
programming, we refer the reader to the literature; for example, see [7]. We believe that these
non-classical languages will open up new application areas for logic programming.
References
[1] M. Abadi and Z. Manna. Temporal logic programming. In Proceedings of the 1987 Symposium
on Logic Programming, pages 4–16, San Fransisco, Calif, 1987. IEEE Computer Society Press.
[2] T. Aoyagi, M. Fujita, and T. Moto-oka. Temporal logic programming language Tokio. In
E. Wada, editor, Logic Programming’85, volume 221 of LNCS, pages 138–147. Springer-Verlag,
1986.
7
[3] M. Baudinet. Temporal logic programming is complete and expressive. In Conference Record
of the Sixteenth ACM Symposium on Principles of Programming Languages, pages 267–280,
Austin, Texas, January 1989. The Association for Computing Machinery.
[4] S. Ceri, G. Gottlob, and L. Tanca. Logic Programming and Databases. Springer-Verlag, Berlin
Heidelberg, 1990.
[5] W. F. Clocksin. Logic programming and digital analysis. Journal of Logic Programming,
4:59–82, March 1987.
[6] L. Fariñas del Cerro. MOLOG: A system that extends PROLOG with modal logic. New
Generation Computing, 4:35–50, 1986.
[7] L. Fariñas del Cerro and M. Penttonen, editors. Intensional Logics for Programming. Oxford
University Press, 1992. ISBN 019-853775-1.
[8] Melvin Fitting. Enumeration operators and modular logic programming. Journal of Logic
Programming, 4:11–21, 1987.
[9] D. M. Gabbay. Modal and temporal logic programming. In A. Galton, editor, Temporal
Logics and Their Applications, pages 197–237. Academic Press, 1987.
[10] D. M. Gabbay. A temporal logic programming machine [modal and temporal logic programming, Part 2]. Department of Computing, Imperial College, November 1989.
[11] W. H. Mitchell and A. A. Faustini. The intensional logic language InTense. In Proceedings
of the 1989 International Symposium on Lucid and Intensional Programming, Arizona State
University, May 8 1989.
[12] B. Moszkowski. Executing Temporal Logic Programs. Cambridge University Press, 1986.
[13] M. A. Orgun and W. W. Wadge. Theory and practice of temporal logic programming. In
L. Fariñas del Cerro and M. Penttonen, editors, Intensional Logics for Programming, pages
23–50. Oxford University Press, 1992.
[14] M. A. Orgun and W. W. Wadge. Chronolog admits a complete proof procedure. In Proceedings
of the Sixth International Symposium on Lucid and Intensional Programming, pages 120–135,
Université Laval, Québec City, Canada, 1993.
[15] N. Rescher and A. Urquhart. Temporal Logic. Springer-Verlag, 1971.
8