Temporal Constraints for
Concurrent Object Synchronisation
WOOD, Warsaw 12.04.03
Vladimiro Sassone
with Giuseppe Milicia
What does Inheritance do, after all?
class Buffer {
void put(Object v) { ...; } void get() { ...; }
... }
class Lock { ...
void lock() { ...; } void unlock() { ...; } }
Influence Buffer inheriting behaviour from Lock.
class LockableBuffer extends Buffer, Lock{ }
What does Inheritance do, after all?
class Buffer {
void put(Object v) { ...; } void get() { ...; }
... }
class Lock { ...
void lock() { ...; } void unlock() { ...; } }
Influence Buffer inheriting behaviour from Lock.
What does Inheritance do, after all?
class Buffer {
void put(Object v) { ...; } void get() { ...; }
... }
class Lock { ...
void lock() { ...; } void unlock() { ...; } }
Influence Buffer inheriting behaviour from Lock.
Objects and Concurrency
Objects
: A fundamental, state-of-the-art concept for engineering complex software systems. (Design Patterns, Refactoring, . . .)Concurrency
: A fundamental technology to meet today’s demands on software functionalities. (Internet, Mobile and Embedded Devices, Software Agents, . . .)Alas, a difficult marriage
Synchronisation
of concurrent activities andinheritance
do not mix:Inheritance Anomaly
(Yonezawa [1987])So bad to justify
banning
inheritance from OO languages! (America [1991])The plan
Explain the phenomenon via examples;Illustrate the driving lines of the main existing approaches;
Objects and Concurrency
Objects
: A fundamental, state-of-the-art concept for engineering complex software systems. (Design Patterns, Refactoring, . . .)Concurrency
: A fundamental technology to meet today’s demands on software functionalities. (Internet, Mobile and Embedded Devices, Software Agents, . . .)Alas, a difficult marriage
Synchronisation
of concurrent activities andinheritance
do not mix:Inheritance Anomaly
(Yonezawa [1987])So bad to justify
banning
inheritance from OO languages! (America [1991])The plan
Explain the phenomenon via examples;Illustrate the driving lines of the main existing approaches;
Objects and Concurrency
Objects
: A fundamental, state-of-the-art concept for engineering complex software systems. (Design Patterns, Refactoring, . . .)Concurrency
: A fundamental technology to meet today’s demands on software functionalities. (Internet, Mobile and Embedded Devices, Software Agents, . . .)Alas, a difficult marriage
Synchronisation
of concurrent activities andinheritance
do not mix:Inheritance Anomaly
(Yonezawa [1987])So bad to justify
banning
inheritance from OO languages! (America [1991])The plan
Explain the phenomenon via examples;
Illustrate the driving lines of the main existing approaches;
Objects and Concurrency
Objects
: A fundamental, state-of-the-art concept for engineering complex software systems. (Design Patterns, Refactoring, . . .)Concurrency
: A fundamental technology to meet today’s demands on software functionalities. (Internet, Mobile and Embedded Devices, Software Agents, . . .)Alas, a difficult marriage
Synchronisation
of concurrent activities andinheritance
do not mix:Inheritance Anomaly
(Yonezawa [1987])So bad to justify
banning
inheritance from OO languages! (America [1991])Concurrency and Interference
The problem
: x := 0; ( x := x + 1kx := x + 2 ). Then, x ∈ {1,2,3}.The solutions:
Operational Mechanisms:
Semaphores and Locks, . . .
Linguistic Constructs:
Critical Regions and Monitors, . . .
Alternative Models:
Message Passing, Resource-Based, . . .
Concurrency and Interference
The problem
: x := 0; ( x := x + 1kx := x + 2 ). Then, x ∈ {1,2,3}.The solutions:
Operational Mechanisms:
Semaphores and Locks, . . .
Linguistic Constructs:
Critical Regions and Monitors, . . .
The Java Concurrency Model
public class Buffer {
protected Object[] buf;
protected int MAX, current = 0;
Buffer(int max) { MAX = max;
buf = new Object[MAX]; }
public synchronized Object get() throws Exception { while (current <= 0) wait();
Object ret = buf[--current];
notifyAll(); return ret; }
public synchronized void put(Object v) throws Exception { while (current >= MAX) wait();
Business and Synchronisation Code
/o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o client /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o objectIn
sequential programming
, clients can be asked to behave well. E.g., don’t get unless you have put. (Synchronisation code and Business code.)/o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o client /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o object /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o client
In
sequential programming
, clients can be asked to behave well. E.g., don’t get unless you have put.In
concurrency
, the resourcemust
containsynchronisation code
. This results essentially in methodsnot being available
at certain moments in time.Concurrent object oriented programs in common programming languages consist of
Business and Synchronisation Code
/o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o client /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o object /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o clientIn
sequential programming
, clients can be asked to behave well. E.g., don’t get unless you have put.In
concurrency
, the resourcemust
containsynchronisation code
. This results essentially in methodsnot being available
at certain moments in time.Concurrent object oriented programs in common programming languages consist of
Business and Synchronisation Code
/o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o client /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o object /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o /o clientIn
sequential programming
, clients can be asked to behave well. E.g., don’t get unless you have put.In
concurrency
, the resourcemust
containsynchronisation code
. This results essentially in methodsnot being available
at certain moments in time.Concurrent object oriented programs in common programming languages consist of
The Inheritance Anomaly
Inheritance Anomaly
: Adding a new methodmorally
unrelated, forces the redefinition of all other methods of a class.class Buffer { ...
void put(Object el) {
if ("buffer not full") ... }
Object get() {
if ("buffer not empty") ... }
}
Add a method
freeze
.Chances are that the synchronisation code in Buffer must be totally rewritten for that. All approaches to the anomaly so far consist of
disentangling
business andThe Inheritance Anomaly
Inheritance Anomaly
: Adding a new methodmorally
unrelated, forces the redefinition of all other methods of a class.class Buffer { ...
void put(Object el) {
if ("buffer not full") ... }
Object get() {
if ("buffer not empty") ... }
} Add a method
freeze
.Chances are that the synchronisation code in Buffer must be totally rewritten for that. All approaches to the anomaly so far consist of
disentangling
business andThe Inheritance Anomaly
Inheritance Anomaly
: Adding a new methodmorally
unrelated, forces the redefinition of all other methods of a class.class Buffer { ...
void put(Object el) {
if ("buffer not full") ... }
Object get() {
if ("buffer not empty") ... }
}
Add a method
freeze
.Chances are that the synchronisation code in Buffer must be totally rewritten for that. All approaches to the anomaly so far consist of
disentangling
business andPartitioning of States
State Partition
: Introduce an explicit partition of the object’s state, and explicitenabling conditions for methods.
Example
. In the case of Buffer, choose empty, partial, full and the declarations:put: requires not full
get: requires not empty Then
Object get() { ...
if ("buffer is now empty ") become empty; else become partial;
Partitioning of States
State Partition
: Introduce an explicit partition of the object’s state, and explicitenabling conditions for methods.
Example
. In the case of Buffer, choose empty, partial, full and the declarations:put: requires not full
get: requires not empty
Then
Object get() { ...
if ("buffer is now empty ") become empty;
else become partial; return res;
Partition of States
This solves the problem only very
partially
.Consider adding get2 which retrieves
two
elements at once. Then, the partition empty and full is not enough anymore.Need to distinguish those states where there is exactly one element: single.
Correspondingly, refine it to be:
get2: requires not empty or single
Object get() { ...
if ("buffer is now empty ") become empty;
else if ("buffer is singleton") become single; else become partial;
Partition of States
This solves the problem only very
partially
.Consider adding get2 which retrieves
two
elements at once. Then, the partition empty and full is not enough anymore.Need to distinguish those states where there is exactly one element: single. Correspondingly, refine it to be:
get2: requires not empty or single
Object get() { ...
if ("buffer is now empty ") become empty;
else if ("buffer is singleton") become single; else become partial;
Partition of States
This solves the problem only very
partially
.Consider adding get2 which retrieves
two
elements at once. Then, the partition empty and full is not enough anymore.Need to distinguish those states where there is exactly one element: single.
Correspondingly, refine it to be:
get2: requires not empty or single
Object get() { ...
if ("buffer is now empty ") become empty;
else if ("buffer is singleton") become single; else become partial;
History-Sensitiveness of Acceptable States
When methods’ enabling depends on the
history
of objects, we have a form of the anomaly so-calledhistory-sensitive
.For instance, a method withdraw available only after a method authenticate has been completed.
History-Sensitiveness of Acceptable States
When methods’ enabling depends on the
history
of objects, we have a form of the anomaly so-calledhistory-sensitive
.For instance, a method withdraw available only after a method authenticate has been completed.
History Buffer
public class HistoryBuffer extends Buffer { boolean afterGet = false;
public HistoryBuffer(int max) super(max);
public synchronized Object gget() throws Exception { while ( current <= 0 || afterGet ) wait();
Object ret = buf[--current]; afterGet = false;
notifyAll(); return ret; }
public synchronized Object get() throws Exception { while (current <= 0) wait();
Object ret = buf[--current]; afterGet = true;
notifyAll(); return ret; }
History Buffer, again
public class HistoryBuffer extends Buffer { boolean afterGet = false;
public HistoryBuffer(int max) { super(max); }
public synchronized Object gget() throws Exception { while ( current <= 0 || afterGet) wait();
afterGet = false; return super.get(); }
public synchronized Object get() throws Exception { Object o = super.get();
afterGet = true; return o;
}
public synchronized void put(Object v) throws Exception { super.put(v);
Modification of Acceptable States
Anomaly when
mix-in classes
are used to add behaviour to object via multiple inheritance.class Lock { ...
void lock() { ...; } void unlock() { ...; } }
Trying to influence the enabling conditions of a class, by inheritance.
class LockableBuffer extends Buffer, Lock{ } Of course, this does no much towards having a
lockable buffer, in any language I know of.
Modification of Acceptable States
Anomaly when
mix-in classes
are used to add behaviour to object via multiple inheritance.class Lock { ...
void lock() { ...; } void unlock() { ...; } }
Trying to influence the enabling conditions of a class, by inheritance.
class LockableBuffer extends Buffer, Lock{ }
Of course, this does no much towards having a lockable buffer, in any language I know of.
JEEG
Jeeg
tackles the (History-Sensitive) Inheritance Anomaly. It is:an aspect-oriented superimposition of two separate languages
Java
(no synchronized(), wait(), notify(), and notifyAll() for business code);Linear Time Temporal Logic
for synchronisation code (method guards). public class MyClass {sync { m : φ; .... }
...// Standard Java class definition }
m is a method id and φ, the
guard
, is a formula in a givenconstraint
language. When m is invoked, the thread iskept on hold
unless φ. When the condition is true, allwaiting
threads areawaken
. m is implicitlysynchronized
.JEEG
Jeeg
tackles the (History-Sensitive) Inheritance Anomaly. It is:an aspect-oriented superimposition of two separate languages
Java
(no synchronized(), wait(), notify(), and notifyAll() for business code);Linear Time Temporal Logic
for synchronisation code (method guards).public class MyClass {
sync { m : φ; .... }
...// Standard Java class definition }
JEEG
Jeeg
tackles the (History-Sensitive) Inheritance Anomaly. It is:an aspect-oriented superimposition of two separate languages
Java
(no synchronized(), wait(), notify(), and notifyAll() for business code);Linear Time Temporal Logic
for synchronisation code (method guards).public class MyClass {
sync { m : φ; .... }
...// Standard Java class definition }
The logic
Logic
: a trade-off betweenexpressiveness
andefficiency
: its formulae must be verified at every method invocation!Linear temporal logic
(past tense)φ ::= AP | !φ | φ || φ | Previous φ | φ Since φ
AP are pure boolean expressions with no:
side-effects
,references to objects
.method invocations
,and it only refers to
private/protected
fields of the class it belongs to.Derived connectives
:φ && ψ ,!(!φ ||!ψ); Sometime φ , true Since φ; Always φ , !Sometime !φ.
The logic
Logic
: a trade-off betweenexpressiveness
andefficiency
: its formulae must be verified at every method invocation!Linear temporal logic
(past tense)φ ::= AP | !φ | φ || φ | Previous φ | φ Since φ
AP are pure boolean expressions with no:
side-effects
,references to objects
.method invocations
,and it only refers to
private/protected
fields of the class it belongs to.Derived connectives
:φ && ψ ,!(!φ ||!ψ); Sometime φ , true Since φ; Always φ , !Sometime !φ.
The logic
Logic
: a trade-off betweenexpressiveness
andefficiency
: its formulae must be verified at every method invocation!Linear temporal logic
(past tense)φ ::= AP | !φ | φ || φ | Previous φ | φ Since φ
AP are pure boolean expressions with no:
side-effects
,references to objects
.method invocations
,and it only refers to
private/protected
fields of the class it belongs to.An Object’s History
A generic computation π from o’s perspective.
h00 · · ·h 0
j0o.m1h
1
0 · · · h 1
j1o.m2h
2
0 · · ·h 2
j2 . . .
Here only the part of hkjk containing the values of private/protected, non-reference variables of o, say σk, can affect evaluation. Therefore, we take
Ho(π) ≡ σ0
m1
→ σ1
m2
→ σ2
m3
→ σ3 . . .
We think of Ho(π) as
Ho ≡ σ0σ1σ2σ3 . . .
where σi binds the special identifier event to (a value representing method) mi.
An Object’s History
A generic computation π from o’s perspective.
h00 · · ·h 0
j0o.m1h
1
0 · · · h 1
j1o.m2h
2
0 · · ·h 2
j2 . . .
Here only the part of hkjk containing the values of private/protected, non-reference variables of o, say σk, can affect evaluation. Therefore, we take
Ho(π) ≡ σ0
m1
→ σ1
m2
→ σ2
m3
→ σ3 . . .
We think of Ho(π) as
Ho ≡ σ0σ1σ2σ3 . . .
where σi binds the special identifier event to (a value representing method) mi.
An Object’s History
A generic computation π from o’s perspective.
h00 · · ·h 0
j0o.m1h
1
0 · · · h 1
j1o.m2h
2
0 · · ·h 2
j2 . . .
Here only the part of hkjk containing the values of private/protected, non-reference variables of o, say σk, can affect evaluation. Therefore, we take
Ho(π) ≡ σ0
m1
→ σ1
m2
→ σ2
m3
→ σ3 . . .
We think of Ho(π) as
Ho ≡ σ0σ1σ2σ3 . . .
where σi binds the special identifier event to (a value representing method) mi.
Concurrent Objects’ Histories
n = 2
inc ()
n = 0 n = 1 n = 0
inc () dec ()
n = 0 inc () n = 1
C1
C2
C1
n = 0
C1
n = 1
C1
n = 2
C2
n = 0 C1
n = 1
C2
n = 0 C1
n = 1
C2
n = 1 C1
n = 1
C2
Interpretation of Formulae on Object Histories
Let Σ denote Ho(π). For all indexes k in Σ, we define Σk |= φ, that is φ holds at time k, by structural induction on φ as follows.
Σk |= p iff σk |= p (p is true at σk)
Σk |= !φ iff not Σk |= φ
Σk |= φ || ψ iff Σk |= φ or Σk |= ψ
Σk |= Previous φ iff k > 0 and Σk−1 |= φ
Σk |= φ Since ψ iff Σj |= ψ for some j ≤ k,
Buffer in JEEG
public class Buffer { sync {
put : current < MAX;
get : current > 0; }
protected Object[] buf;
protected int MAX, current = 0;
Buffer(int max) {
MAX = max; buf = new Object[MAX]; }
public Object get() throws Exception { Object ret = buf[--current];
return ret; }
History Buffer in JEEG
public class HistoryBuffer extends Buffer { sync {
gget: Previous (event != get) && current > 0; }
public HistoryBuffer(int max) { super(max);
}
public Object gget() throws Exception { Object ret = buf[--current];
return ret; }
Lockable Buffer in JEEG
public interface Lock { public void lock(); public void unlock(); }
public class LockBuf extends Buffer implements Lock { sync {
get : super.getConstr && !Previous (event == lock);
put : super.putConstr && !Previous (event == lock);
lock : !Previous (event == lock);
unlock : true; }
public LockBuf(int max) { super(max); } public void lock() { }
Expressiveness of JEEG
It is generally hard to formalise to what extent the anomaly is removed. Nicely,
Jeeg
allows for a“quantitative”
analysis.Expressiveness of LTL
: A set of state sequences X is the set of all Σs that satisfy a given φ if and only if X is a star-free regular language. (Zuck [1986])Star-free Regular Languages
:re ::= ² | a | re · re | re + re | ¬r (| re∗)
State for
: p ∈ AC ⊂ AP;Sequence of states
: P ∈ A∗C. (Σ |= P iffΣk |= Pk)
Theorem
(Characterizing CL). For φ a formula on C, X = {Σ | Σ |= φ} iffthere exists re on AC such that Σ ∈ X iff Σ |= P for some P ∈ re.
Special case
: Only atomic propositions of the kind event == m.Expressiveness of JEEG
It is generally hard to formalise to what extent the anomaly is removed. Nicely,
Jeeg
allows for a“quantitative”
analysis.Expressiveness of LTL
: A set of state sequences X is the set of all Σs that satisfy a given φ if and only if X is a star-free regular language. (Zuck [1986])Star-free Regular Languages
:re ::= ² | a | re · re | re + re | ¬r (| re∗)
State for
: p ∈ AC ⊂ AP;Sequence of states
: P ∈ AC∗. (Σ |= P iff Σk |= Pk)Theorem
(Characterizing CL). For φ a formula on C, X = {Σ | Σ |= φ} iffthere exists re on AC such that Σ ∈ X iff Σ |= P for some P ∈ re.
Special case
: Only atomic propositions of the kind event == m.Expressiveness of JEEG
It is generally hard to formalise to what extent the anomaly is removed. Nicely,
Jeeg
allows for a“quantitative”
analysis.Expressiveness of LTL
: A set of state sequences X is the set of all Σs that satisfy a given φ if and only if X is a star-free regular language. (Zuck [1986])Star-free Regular Languages
:re ::= ² | a | re · re | re + re | ¬r (| re∗)
State for
: p ∈ AC ⊂ AP;Sequence of states
: P ∈ AC∗. (Σ |= P iff Σk |= Pk)Theorem
(Characterizing CL). For φ a formula on C, X = {Σ | Σ |= φ} iffthere exists re on AC such that Σ ∈ X iff Σ |= P for some P ∈ re.
Special case
: Only atomic propositions of the kind event == m.Expressiveness of JEEG
It is generally hard to formalise to what extent the anomaly is removed. Nicely,
Jeeg
allows for a“quantitative”
analysis.Expressiveness of LTL
: A set of state sequences X is the set of all Σs that satisfy a given φ if and only if X is a star-free regular language. (Zuck [1986])Star-free Regular Languages
:re ::= ² | a | re · re | re + re | ¬r (| re∗)
State for
: p ∈ AC ⊂ AP;Sequence of states
: P ∈ AC∗. (Σ |= P iff Σk |= Pk)Theorem
(Characterizing CL). For φ a formula on C, X = {Σ | Σ |= φ} iffthere exists re on AC such that Σ ∈ X iff Σ |= P for some P ∈ re.
Special case
: Only atomic propositions of the kind event == m.Examples
HistoryBuffer
: the temporal constraintPrevious event != get
can be expressed by the following star-free regular expressions.
¬(A∗ · get) where A∗ , ² + ¬².
The temporal constraint
Sometime m , true Since m.
corresponds to
Limitations of LTL: No Counting
public class SharedResource { sync {
request: true;
release: true; }
public void request() { ... } public void release() { ... } ...
}
Define a class
SeizableResource
which allows exclusive access to the shared resource: An additional methodexclusiveRequest
must be provided.Clearly, this leads to identify a pattern of events such as:
M ::= ² | request M release | MM | ...
Runtime Evaluation of CL Expressions
Given a finite trace Σ and a LTL formula φ, does Σ |= φ ?
Traditionally: build a
Buchi automata
to ‘model-check’ sequences. Dealing with past tense operators gives us an advantage: an ‘online
’ algorithm.Build the syntax tree of the formula;
Associate variables before and now to every node, initially set to false; Visit the tree depth-first and simultaneously assign φ.before := φ.now and
φ.now as follows.
previous now := φ0.before
since now := φ1.now or (before and φ0.now)
or now := φ0.now or φ1.now
not now := not φ0.now
AP now := eval(φ)
Runtime Evaluation of CL Expressions
Given a finite trace Σ and a LTL formula φ, does Σ |= φ ?
Traditionally: build a
Buchi automata
to ‘model-check’ sequences. Dealing with past tense operators gives us an advantage: an ‘online
’ algorithm.Build the syntax tree of the formula;
Associate variables before and now to every node, initially set to false; Visit the tree depth-first and simultaneously assign φ.before := φ.now and
φ.now as follows.
previous now := φ0.before
since now := φ1.now or (before and φ0.now)
or now := φ0.now or φ1.now
not now := not φ0.now
AP now := eval(φ)
(/).*-+,
φ1 : : : : : : :
φ0 ¥¥¥¥
¥¥¥
before, now
(/).*-+,
φ
before, now
(/).*-+,
φ
An Example
Example
: Let us consider the evaluation of the temporal formulaPrevious(x == 1)
x = 0
inc ()
x = 1
inc ()
Previous
now = false before = false
x == 1
now = false before = false
Previous
now = false before = false
x == 1
now = true before = false
Previous
now = true before = false
x == 1
now = false before = true
x = 2
dec ()
x = 1
Previous
now = false before = true
x == 1
The Synchronisation Manager
Formulae must be evaluated after every method execution. This is done by a
synchronization manager
viaMethod Call Interception
. Ittakes control at method call and checks (not evaluates) the constraint for the method.
If it holds, control goes to the method code; otherwise the synchronization manager performs a wait(), putting the object to sleep.
After the method execution, control shifts back to the manager, which now re-evaluates the synchronization constraints.
After updating the formulae logic value, the manager issues a notifyAll() statement. Blocked methods may then attempt to proceed again.
Benchmarks: Object Creation
0 20 40 60 80 100 120 140 160 180
0 50 100 150 200
Constraint Size
Time in ms
Machine 3
Machine 2
Machine 4
Benchmarks: Method Call
0 20 40 60 80 100 120 140 160
Time in ms
Machine 1
Machine 2
Machine 3
Benchmarks: Details of Method Call
1 30 50 73 122 1 2 4 8 16 32 64 0 200 400 600 800 1000 1200Time in ms
Constraint Size Threads
Machine 2 Machine 3
1 30 50 73 122 1 2 4 8 16 32 64 0 200 400 600 800 1000 1200 1400 1600
Time in ms
Constraint Size Threads
Benchmarks: Comparison
0 20 40 60 80 100 120 140
0 50 100 150 200 250
Threads
Time in ms
Machine 3
Performance Evaluation
Testing
shows that:Under
low-load
(below 70 threads) even complex synchronization constraints yield little performance overhead.Conclusion
Jeeg
Synchronization constraints written in LTL and specified in a aspect-oriented, declarative manner.
CL is helpful in treating the inheritance anomaly.
Characterisation of CL in terms of regular languages
Efficiently implementable (available at http://www.brics.dk/~milicia/Jeeg).
Future Work
:Quantified linear temporal logic (QLTL) or monadic second order logic (MSOL), ‘second order’ variations of LTL of greater expressiveness.
Conclusion
Jeeg
Synchronization constraints written in LTL and specified in a aspect-oriented, declarative manner.
CL is helpful in treating the inheritance anomaly.
Characterisation of CL in terms of regular languages
Efficiently implementable (available at http://www.brics.dk/~milicia/Jeeg).
Future Work
:Quantified linear temporal logic (QLTL) or monadic second order logic (MSOL), ‘second order’ variations of LTL of greater expressiveness.