comp.lang.ada
 help / color / mirror / Atom feed
* Safety-critical development in Ada and Eiffel
  1997-07-09  0:00 Is ADA as good for graphics programming as C? (WAS: Re: Avoiding the second historic mistake) Tucker Taft
@ 1997-07-10  0:00 ` Don Harrison
  1997-07-10  0:00   ` Joe Gwinn
                     ` (5 more replies)
  0 siblings, 6 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-10  0:00 UTC (permalink / raw)



Tucker Taft wrote:

:Don Harrison (donh@syd.csa.com.au) wrote:
:
:: Donovan Baarda wrote:
:
:: :Eiffel is IMHO a better choice for safety-critical applications without
:: :excessive real time requirements. Design by contract obviously (and
:: :measurably?) contributes significantly to program safety. Combining this
:: :with a complete inheritanc heirachy of library classes with all the
:: :contracts defined and inheritable has to make a huge difference.
:
:: I agree on all points. ...
:
:I'm curious what you mean by safety-critical.

Probably the same as you - systems which must function correctly (meet all 
functional requirements including timing constraints) where failure to do so
will incur great cost (loss of life, financial meltdowns etc.)


:In my experience with safety-critical applications, you 
:cannot have any significant amount of out-of-line run-time
:support, 

What, apart from managing concurrency, do you have in mind here?

In terms of the Eiffel concurrency overhead, it would probably be comparable
to that of Ada tasking. Optimisations and sensible design would make that 
acceptable, IMO.


:and little or no use of dynamic storage allocation after 
:system startup.
:
:Eiffel's dependence on dynamic storage allocation and garbage 
:collection basically rules it out for most (serious) safety-critical
:applications, despite all its admittedly nice invariants and assertions.

Both of these issues can be dealt with in Eiffel:

  1) Dynamic storage allocation - The solution here (as in Ada) is to use 
     a pre-allocated memory pool for HRT parts of the system so eliminating 
     the need for dynamic allocation under HRT conditions.

  2) Garbage collection - This can be solved by turning memory allocation and
     deallocation (GC) off after start-up. Most Eiffel implementations already 
     allow you to turn GC off so vendors would just have to add the ability 
     to control allocation as well. It could work as follows:

       - At startup, dynamic storage would be pre-allocated as per 1).
       - Dynamic storage allocation and GC would be turned off.
       - The thread operates under HRT conditions communicating minimally
         with other threads.
       - At shutdown, dynamic storage allocation and GC are turned on again.

     Note that in a concurrent context, such memory control would occur on a 
     per-thread basis so allocation and GC would work as normal on less critical 
     threads.


:One of the important features of Ada in the safety-critical domain
:is that there is a very useful subset that makes little or no use 
:of out-of-line run-time support, and essentially no use of dynamic
:storage allocation.   

What is included in that subset?


:Finally there are available tools (such as the "SPARK" tools from Praxis, 
:Ltd.) which add support for all of the kinds of assertions that
:Eiffel has, including full static analysis and theorem
:proving support of the assertions, ...

Sounds like a step in the right direction, however I guess the assertions are 
not inheritable. If so, they are not as powerful as Eiffel's.

 
[...]
 
:It is not so easy to take a language like Eiffel that is fundamentally 
:oriented toward dynamic storage allocation (and pervasive dynamic binding), ...

Eiffel implementations optimise a high percentage of dynamic calls to static 
ones - 80-90%? Also, since the overhead of the calling mechanism is just part
of the cost of making the call (the total cost includes execution of the body),
the resultant penalty for default dynamic binding is reduced to 5-10% - 
obviously not worth getting excited over, even for HRT systems.


:Ada95 was designed to be able to support programming in a way
:that minimizes dynamic storage allocation, unnecessary dynamic binding, etc.
:while still supporting the object-oriented paradigm and a very strong
:and separately compilable contract between the clients 
:and the implementation(s) of an abstract interface.  The "contract"
:enforced at compile-time by the Ada compiler is much stronger than
:the contract enforced at compile-time by most compilers, since it
:includes strong type distinctions between otherwise equivalent scalar,
:array, and pointer types, plus compiler-enforced parameter modes,
:and the ability to use formal parameter names to verify actual/formal
:parameter association.

Some of these aren't necessary and have been omitted in the design of Eiffel. 
Of the rest, Eiffel effectively delivers the same (or an equivalent) 
functionality or enables you to acheive it through good design. 

A couple of points, however..

1) Eiffel automatically generates interfaces from class texts (a good thing, 
   IMO) but I'm unsure which impementations routinely recompile the "body" 
   of a class after changes that *don't* change the "interface". 
   None should, IMO, as it's technically possible to detect this situation.

2) Eiffel's contracts are stronger, more general, more flexible and more powerful
   than in standard Ada. This doesn't mean Ada's contracting is useless by 
   any means. It's a tribute to the designers of Ada83 that support for 
   predefined contracts was included at the time it was designed. I'm 
   disappointed, of course, that they were omitted from Ada95.

3) Named parameter association is not necessary with systematic, sensible naming.
   I confess to still using them in Ada (through force of habit) but usually 
   find that my formal and actual names are identical. Using named association 
   under such circumstances only serves to clutter the software text.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00 ` Safety-critical development in Ada and Eiffel Don Harrison
  1997-07-10  0:00   ` Joe Gwinn
  1997-07-10  0:00   ` Ken Garlington
@ 1997-07-10  0:00   ` Mike Stark
  1997-07-11  0:00     ` Donovan Baarda
  1997-07-11  0:00   ` Kazimir Majorinc
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 255+ messages in thread
From: Mike Stark @ 1997-07-10  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Tucker Taft wrote:
> 
<snip> 
> :and little or no use of dynamic storage allocation after
> :system startup.
> :
> :Eiffel's dependence on dynamic storage allocation and garbage
> :collection basically rules it out for most (serious) safety-critical
> :applications, despite all its admittedly nice invariants and assertions.
> 
> Both of these issues can be dealt with in Eiffel:
> 
>   1) Dynamic storage allocation - The solution here (as in Ada) is to use
>      a pre-allocated memory pool for HRT parts of the system so eliminating
>      the need for dynamic allocation under HRT conditions.

Does this "pre-allocated memory pool" mean that you will know exactly
what address
each object's data will reside at, or merely that you dynamically
allocate memory
at initialization and do not dynamically allocate after initialization
is complete?

My experience with flight software people here at Goddard (and it is
admittedly
limited) is that they are very conservative about knowing *exactly*
where
everything is located in memory -- they want the equivalent of a FORTRAN
common
block, which can be achieved in Ada (or C++, to be fair) by declaring
variables
of a tagged type in a package specification, e.g.

package Flight_Objects is
  DSS1,DSS2 : aliased Digital_Sun_Sensor.Instance; 
  -- Digital_Sun_Sensor.Instance is a tagged type in the Sensor class
hierarchy
  -- all the types below are tagged
  Sun : aliased Solar_Model.Instance;  
  Orbit : aliased Orbit_Propagator.Instance;
  -- etc.
  
end Flight_Objects;

(the aliased keyword in Ada allows pointers to statically declared
objects)

This is *not* the same thing as allocating objects at initialization --
the heap is 
not involved at all.
> 
>   2) Garbage collection - This can be solved by turning memory allocation and
>      deallocation (GC) off after start-up. 

Agreed -- this is reasonable approach
<snip>
> 
> :It is not so easy to take a language like Eiffel that is fundamentally
> :oriented toward dynamic storage allocation (and pervasive dynamic binding), ...
> 
> Eiffel implementations optimise a high percentage of dynamic calls to static
> ones - 80-90%? Also, since the overhead of the calling mechanism is just part
> of the cost of making the call (the total cost includes execution of the body),
> the resultant penalty for default dynamic binding is reduced to 5-10% -
> obviously not worth getting excited over, even for HRT systems.

Both Ada and Eiffel provide information to the compiler that allows
optimization
of dynamic calls to static ones -- this is an advantage of these 2
languages over
a less rigorously typed language such as Smalltalk. However, calls to
constructors
and destructors are exceedingly expensive compared to other method
calls, at least
in our division's experiences with C++.

In the interests of full disclosure, I will say my knowledge of Ada is
through
actual use and of Eiffel is purely academic, so I don't have the same
intuition
for what works in reality when you are talking about Eiffel.  I very
much like
the ideas behind Eiffel, especially the concept of programming by
contract.  

Despite that, my guess is that flight software people at Goddard would
not look kindly
on the fact that all objects must be dynamically allocated, and that
this goes double
for the manned space program or for the FAA's certification of
airliners. I am
interested in any contrary opinions, though, especially from people who
actually
have used Eiffel for safety critical systems.

--------------------------------------------------------------------------------
Michael Stark                                                  
NASA/GSFC                                           
Phone: (301) 286-5048                                   Code 551
Fax:    (301) 286-0245                                   Greenbelt, MD
20771
 e-mail: michael.e.stark@gsfc.nasa.gov
"I don't give them hell.  I tell the truth and they THINK it's hell!" 
Harry S. Truman
--------------------------------------------------------------------------------




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00 ` Safety-critical development in Ada and Eiffel Don Harrison
  1997-07-10  0:00   ` Joe Gwinn
@ 1997-07-10  0:00   ` Ken Garlington
  1997-07-11  0:00     ` Ted Velkoff
  1997-07-10  0:00   ` Mike Stark
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-10  0:00 UTC (permalink / raw)




> Eiffel implementations optimise a high percentage of dynamic calls to
static 
> ones - 80-90%? Also, since the overhead of the calling mechanism is just
part
> of the cost of making the call (the total cost includes execution of the
body),
> the resultant penalty for default dynamic binding is reduced to 5-10% - 
> obviously not worth getting excited over, even for HRT systems.

I dunno. I've seen more than one safety-critical embedded real-time systems
that
had to be re-worked at some cost to recover 5-10% overhead.


> 2) Eiffel's contracts are stronger, more general, more flexible and more
powerful
>    than in standard Ada. This doesn't mean Ada's contracting is useless
by 
>    any means. It's a tribute to the designers of Ada83 that support for 
>    predefined contracts was included at the time it was designed. I'm 
>    disappointed, of course, that they were omitted from Ada95.

I'm not sure what was in Ada83 that was omitted in Ada95; however, I have
noticed
that Eiffel examples posted in various places tend to have assertions that
are
fairly simple in nature (range checks), etc that are directly representable
in Ada.
Those that aren't tend to be easy to do with good Ada design using
exceptions (sort
of the same "good design principles" that you discussed using in Eiffel to
get
the features made explicit in Ada).

I think I'd like to see more cases where Eiffel is used in "hard" real-time
safety-critical
systems, and in particular some years of experience where Eiffel accurately
detects -
AND CORRECTS - for faults that are not routinely handled in equivalent Ada
systems
developed by the same vendor. I think that experience is already starting
to emerge with
respect to Ada vs. older languages in this domain, particularly for Ada's
static checks.

> 
> 3) Named parameter association is not necessary with systematic, sensible
naming.
>    I confess to still using them in Ada (through force of habit) but
usually 
>    find that my formal and actual names are identical. 

Not our experience at all, particularly for commonly-used routines within a
system. Named
parameter association is extremely useful, in my experience.

> Using named association 
>    under such circumstances only serves to clutter the software text.

Fortunately, in Ada, you can only use named notation where you want.

> 
> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au
> 
> 
> 




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00 ` Safety-critical development in Ada and Eiffel Don Harrison
@ 1997-07-10  0:00   ` Joe Gwinn
  1997-07-11  0:00     ` Robert S. White
  1997-07-10  0:00   ` Ken Garlington
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 255+ messages in thread
From: Joe Gwinn @ 1997-07-10  0:00 UTC (permalink / raw)



I would comment that we designed a real safety-critical system, the
Microwave Landing System (now cancelled for the convenience of the
Government, in honor of GPS and WAAS), in a subset of Ada83.  (Ada95 was
not available at the time.)

However, there was a lot more to it than to say it was Ada:  We were
required to use a special safety-critical-code subset of Ada, which was
*sharply* smaller than Ada83.  (I no longer recall the details, but I
could dig them up, given a week or three.  It seems to me that it was a
commercial product.)

Perhaps aside from the strong typing, it was not clear just what was left
that was particular to Ada, or why one couldn't do the same radical
simplification to any language one might choose, to much the same effect.

So, I don't know that I buy the theory that Ada83 or Ada95 is the only
choice for safety-critical systems, as what survives isn't really either
language, and one can do the same surgery on any reasonable language. 
What makes it a safety language is the surgery, not the starting point.  

Sort of like Frankenstein's Monster.

Joe Gwinn




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-11  0:00   ` Don Harrison
@ 1997-07-11  0:00     ` James Graves
  1997-07-14  0:00       ` Don Harrison
  1997-07-12  0:00     ` Ken Garlington
  1997-07-16  0:00     ` Alan Brain
  2 siblings, 1 reply; 255+ messages in thread
From: James Graves @ 1997-07-11  0:00 UTC (permalink / raw)



In article <ED5AGp.5MJ@syd.csa.com.au>,
Don Harrison <donh@syd.csa.com.au> wrote:
>
> I suspect that you can also make an Eiffel reference access a statically
> allocated object (expanded type) using a standard class (MEMORY? someone may 
> wish to confirm this). There would certainly be no technical obstacle to 
> providing this capability if it doesn't already exist enabling you to 
> statically allocate whatever memory you require if that's what you want 
> (as in your application domain). 
>

You are not allowed to make a reference to an expanded object in Eiffel,
because of the information hiding principal.  To be able to diddle with
another object's internal data could easily violate the class
invariant.

That's why Mr. Meyer doesn't like Java's ability to perform direct
assignments of an object's data fields (features in Eiffel terms):

    int x;
    Platoon platoon_a;
    x := 50;
    platoon_a.size := x;         <- Could be an invariant violation
				    if Platoons aren't supposed to have
				    that many soldiers.

It could be the programmer should have used platoon_a.set_size(x) which
(presumably) would check the size of it's argument.  Of course in Java,
you can just not export the size variable at all.  Then you would need
to create a function like:

    int get_size()
    {
	return size;
    }

for every variable that clients of the Platoon class should be able to
see (and not set directly).  Does this remind anyone of Smalltalk?

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

As for using Eiffel in a Hard Real Time (HRT) situation, when dynamic
allocation/deallocation of memory is not desired, I suppose you could
create all the needed objects at the start, stick them in a hashtable 
(or array), and then turn off garbage collection.  Then search through
all the rest of the code for creation instructions (!!a.make or such),
and a.clone() procedures.

As you run the system, look at it's memory size after the start, and if
it ever grows, you know you've missed something.  A nice compiler option
would be to report how many dynamically bound calls there were, so you
could eliminate those too if you really wanted.  (ISE claims that even
dynamically bound calls are dispatched in constant time, and I bet other
Eiffel vendors have picked this up too.)

Since learning about the proposed concurrency mechanism in Eiffel, I
would feel more secure using it instead of some threads package for C.
If implemented correctly (which only needs to be done once), it
elliminates a lot of the effot and the contention/locking problems of
parallel programming.


Later,

James Graves





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00 ` Safety-critical development in Ada and Eiffel Don Harrison
                     ` (4 preceding siblings ...)
  1997-07-11  0:00   ` Don Harrison
@ 1997-07-11  0:00   ` Don Harrison
  5 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-11  0:00 UTC (permalink / raw)



I wrote:

:2) Eiffel's contracts are stronger, more general, more flexible and more powerful
:   than in standard Ada. This doesn't mean Ada's contracting is useless by 
:   any means. It's a tribute to the designers of Ada83 that support for 
:   predefined contracts was included at the time it was designed. I'm 
:   disappointed, of course, that they were omitted from Ada95.
                                  ^^^^
This should read "Eiffel-like assertions".


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00   ` Joe Gwinn
@ 1997-07-11  0:00     ` Robert S. White
  1997-07-15  0:00       ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Robert S. White @ 1997-07-11  0:00 UTC (permalink / raw)



In article <gwinn-1007971853320001@dh5152077.res.ray.com>, gwinn@res.ray.com 
says...
   ...snip...
>However, there was a lot more to it than to say it was Ada:  We were
>required to use a special safety-critical-code subset of Ada, which was
>*sharply* smaller than Ada83.  (I no longer recall the details, but I
>could dig them up, given a week or three.  It seems to me that it was a
>commercial product.)
>
>Perhaps aside from the strong typing, it was not clear just what was left
>that was particular to Ada, or why one couldn't do the same radical
>simplification to any language one might choose, to much the same effect.
>
>So, I don't know that I buy the theory that Ada83 or Ada95 is the only
>choice for safety-critical systems, as what survives isn't really either
>language, and one can do the same surgery on any reasonable language. 
   ...snip...

  Sorry Joe I do not agree!  Even if you strip down Ada 83 to a small
subset you still benefit from a lot of the design requirements 
that went into the language.  What really are you alternatives?  C 
or Fortran?  Neither are strongly typed.  Modula 2 or Oberon?  Not 
very widespread.  Just _what_ is your alternative language of choice
(subsetted) for safty critical applications?  Methinks you protest 
too much.  Ada has worked out well for a number of years for safety
critical applications in avionics and other embedded real time control
applications.  What _IS_ the alternate _BETTER_ language of choice?

  I have been implementing software solutions in industry since 1978 
so I think I qualify as an equal curmudgeon to yourself as far is to
what works and what does not work.  No silver bullets, although a good
problem domain understanding, actual software _design_ with peer 
reviews, and software inspections with checklists, and finally
low level whitebox software module tests (along with final qual
tests to requirements) work best for safety-critical software.  Ada is
still an aid, IMO for the end safety-critical objective.  Eiffel has 
yet to prove its advantages to me.  I agree with Ken, most of the 
Eiffel type assertions can also be done in Ada.  Esp GNAT ada95.

_____________________________________________________________________
Robert S. White         -- An embedded systems software engineer





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00   ` Ken Garlington
@ 1997-07-11  0:00     ` Ted Velkoff
  1997-07-12  0:00       ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Ted Velkoff @ 1997-07-11  0:00 UTC (permalink / raw)



Ken Garlington wrote:

> I'm not sure what was in Ada83 that was omitted in Ada95; however, I have
> noticed
> that Eiffel examples posted in various places tend to have assertions that
> are
> fairly simple in nature (range checks), etc that are directly representable
> in Ada.
> Those that aren't tend to be easy to do with good Ada design using
> exceptions (sort
> of the same "good design principles" that you discussed using in Eiffel to
> get
> the features made explicit in Ada).
> 

There's a big difference between assertions and exceptions.

I think a sign that says: "Dangerous curve ahead: left turn required"
(precondition)

is much more useful than one that says: "Accident zone ahead"
(exception declaration)

-- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00 ` Safety-critical development in Ada and Eiffel Don Harrison
                     ` (3 preceding siblings ...)
  1997-07-11  0:00   ` Kazimir Majorinc
@ 1997-07-11  0:00   ` Don Harrison
  1997-07-11  0:00     ` James Graves
                       ` (2 more replies)
  1997-07-11  0:00   ` Don Harrison
  5 siblings, 3 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-11  0:00 UTC (permalink / raw)



[C/C++ groups removed]

Tucker Taft wrote:

::It is not so easy to take a language like Eiffel that is fundamentally 
::oriented toward dynamic storage allocation (and pervasive dynamic binding), ...

I responded:

:Eiffel implementations optimise a high percentage of dynamic calls to static 
:ones - 80-90%? Also, since the overhead of the calling mechanism is just part
:of the cost of making the call (the total cost includes execution of the body),
:the resultant penalty for default dynamic binding is reduced to 5-10% - 
:obviously not worth getting excited over, even for HRT systems.

If even this small overhead is unacceptable, you can force static binding
where necessary by freezing routines. Although you forgo the flexibility of
polymorphism, you can still take advantage of inheritance by virtue of Eiffel
synonyms - these allow you to declare a routine under different names. For an
HRT application, you can use a redefinable version for specialisation but in 
your system, call only the frozen version to force static binding.


Mike Stark wrote:

:Don Harrison wrote:

[...]

:> Both of these issues can be dealt with in Eiffel:
:> 
:>   1) Dynamic storage allocation - The solution here (as in Ada) is to use
:>      a pre-allocated memory pool for HRT parts of the system so eliminating
:>      the need for dynamic allocation under HRT conditions.
:
:Does this "pre-allocated memory pool" mean that you will know exactly
:what address
:each object's data will reside at, or merely that you dynamically
:allocate memory
:at initialization and do not dynamically allocate after initialization
:is complete?

The latter. You don't actually need to know *where* objects are allocated, 
merely that there is sufficient memory to allocate them.

:My experience with flight software people here at Goddard (and it is
:admittedly
:limited) is that they are very conservative about knowing *exactly*
:where
:everything is located in memory -- they want the equivalent of a FORTRAN
:common
:block, which can be achieved in Ada (or C++, to be fair) by [using aliases]...
:
:(the aliased keyword in Ada allows pointers to statically declared
:objects)

I suspect that you can also make an Eiffel reference access a statically
allocated object (expanded type) using a standard class (MEMORY? someone may 
wish to confirm this). There would certainly be no technical obstacle to 
providing this capability if it doesn't already exist enabling you to statically 
allocate whatever memory you require if that's what you want (as in your 
application domain). 


:I am interested in any contrary opinions, though, especially from people who
:actually
:have used Eiffel for safety critical systems.

Your probably unlikely to hear of any because most (including even the Eiffel 
community, unfortunately) seem to overlook its potential for RT systems.


Ken Garlington wrote:

:> 2) Eiffel's contracts are stronger, more general, more flexible and more
:powerful
:>    than in standard Ada. This doesn't mean Ada's contracting is useless
:by 
:>    any means. It's a tribute to the designers of Ada83 that support for 
:>    predefined contracts was included at the time it was designed. I'm 
:>    disappointed, of course, that they were omitted from Ada95.
                                    ^^^^

:I'm not sure what was in Ada83 that was omitted in Ada95; 

Sorry, this should have been "Eiffel-like assertions".


:however, I have noticed
:that Eiffel examples posted in various places tend to have assertions that
:are
:fairly simple in nature (range checks), etc that are directly representable
:in Ada.

Maybe general assertions are more common than you imagine. However, I agree 
that range constraints are roughly covered by Ada subtypes. I use them liberally
for just that purpose.

:Those that aren't tend to be easy to do with good Ada design using
:exceptions ...

Can you clarify what you mean here? If you mean that you can emulate general
assertions in Ada by testing assumptions and raising exceptions when violated,
I agree. In fact that's exactly the style of Ada coding I write these days and
it works great! I routinely apply preconditions, postconditions and check 
instructions to all my code now. Here's an example from some code for managing 
analysis of Sonar tracks (Please excuse the capitals - it's the convention here 
:( ):

  -- ==================================================================
  --
  -- PROCEDURE NAME : REMOVE_TRACK_FROM_ANALYSIS
  --
  --    DESCRIPTION : Remove track from analysis.
  --
  --   Precondition : The specified track is under analysis.
  --  Postcondition : The track is not under analysis and an empty
  --                  position exists.
  --                  
  -- ==================================================================
  
  procedure REMOVE_TRACK_FROM_ANALYSIS (TRACK_INDEX : SAT.TRACK_INDEX_TYPE) is

    POSITION : POSITION_TYPE;
    ANALYSIS_POSITION : POSITION_DATA_TYPE;

  begin
    if SA.ASSERTIONS_ON and then not UNDER_ANALYSIS (TRACK_INDEX) then
      raise SA.PRECONDITION_ERROR;
    end if;

    -- Get it's position.
    POSITION := POSITION_OF_TRACK (TRACK_INDEX);

    -- Set data to defaults.
    ANALYSIS_POSITION := DEFAULT_POSITION_DATA;

    -- Update the tote position data.
    POSITION_DATA(POSITION) := ANALYSIS_POSITION;

    if SA.ASSERTIONS_ON and then (UNDER_ANALYSIS (TRACK_INDEX) 
      or else not ANY_POSITION_VACANT) then
      raise SA.POSTCONDITION_ERROR;
    end if;

  exception
    when others =>
      SEL.LOG_ERROR(
        EXCEPT_STRING => CE.EXCEPTION_NAME,
        PACKAGE_NAME  => PACKAGE_NAME,
        SUBPROG_NAME  => "REMOVE_TRACK_FROM_ANALYSIS" );

      raise;

  end REMOVE_TRACK_FROM_ANALYSIS;


It's not quite as good though because you miss out on inheriting contracts and
it's a little messy to read because there are no distinct assertion clauses
to syntactically separate them from the routine body as in Eiffel.


:I think I'd like to see more cases where Eiffel is used in "hard" real-time
:safety-critical
:systems, and in particular some years of experience where Eiffel accurately
:detects -
:AND CORRECTS - for faults that are not routinely handled in equivalent Ada
:systems
:developed by the same vendor. 

Correct me I misunderstand you.. Are you wondering whether contracting 
helps you to identify more bugs? I can offer my own experience which has 
firmly convinced me of this.

As an example, in our simulation, we have a vehicles object. This is implemented 
as an array of records (they should be variant records discriminated 
on validity, however..). Vehicles are activated and deactivated during the 
course of a "game" by setting a validity flag. I added preconditions to ensure
that other attributes (such as heading) were not queried unless the vehicle was 
active. These simple checks caught a whole bunch of errors that may otherwise 
have gone unnoticed. In the absence of such a check, the problem may only 
have come to our attention if spurious behaviour was observed. In contrast,
the exceptions raised were hard to overlook and ignore and identified these 
problems closer to their source. Consequently, when we (a team of 5) recently 
reached the end of a 5 month long development effort of incremental coding 
and integration testing, the parts of the system that used contracting work 
flawlessly apart from problems resulting from misinterpretation of requirements.

The success was due not only to contracting (other factors such as good design
and some good developers also played a part), but contracting definitely 
contributed significantly.


:I think that experience is already starting
:to emerge with
:respect to Ada vs. older languages in this domain, particularly for Ada's
:static checks.

I agree. Static typing is great for reliability. Complementing it with 
inheritable contracts is even better. 


:> 3) Named parameter association is not necessary with systematic, sensible
:naming.
:>    I confess to still using them in Ada (through force of habit) but
:usually 
:>    find that my formal and actual names are identical. 
:
:Not our experience at all, particularly for commonly-used routines within a
:system. Named
:parameter association is extremely useful, in my experience.

Yes, I guess it's quite handy in many cases. I'm not averse to using it under 
some circumstances.

:> Using named association 
:>    under such circumstances only serves to clutter the software text.
:
:Fortunately, in Ada, you can only use named notation where you want.

Yes, making it optional is a good idea.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00 ` Safety-critical development in Ada and Eiffel Don Harrison
                     ` (2 preceding siblings ...)
  1997-07-10  0:00   ` Mike Stark
@ 1997-07-11  0:00   ` Kazimir Majorinc
  1997-07-12  0:00     ` Ken Garlington
  1997-07-11  0:00   ` Don Harrison
  1997-07-11  0:00   ` Don Harrison
  5 siblings, 1 reply; 255+ messages in thread
From: Kazimir Majorinc @ 1997-07-11  0:00 UTC (permalink / raw)



Eiffel is not safe language. Look for example Shang's article
Is a Cow an Animal? Somewhere on Net. Look at Ellipse CIrcle dilemma.
Should array of superclass be superclass of array of subclass? Noone
knows. Do you accept Liskov Substitution principle? Do you accept
derivation from abstract classes only? Noone knows.  Eiffel's assertions
are good, but it's like to drive motorcycle 250 km/hour and say that
helmet will help you.

For some of us, OO is not only suspect, but even wrong paradigm. It's
place is in laboratory, it is not good for mainstream programming, not
to mention safety. 

If you are interested primarily in safety, you should give up from OO, and
choose good old procedural paradigm. It is not far less powerfull, but it
is certenly safer. Ada 83 is maybe the best answer.  

Regards,
______________________________________________________________
        Kazimir Majorinc,  dipl. ing. of mathematics
 Faculty of Natural Sciences and Math, Uni of Zagreb, Croatia
mailto: kmajor@public.srce.hr    http://public.srce.hr/~kmajor  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-10  0:00   ` Mike Stark
@ 1997-07-11  0:00     ` Donovan Baarda
  1997-07-13  0:00       ` Steve Furlong
  0 siblings, 1 reply; 255+ messages in thread
From: Donovan Baarda @ 1997-07-11  0:00 UTC (permalink / raw)



On Thu, 10 Jul 1997 19:26:17 -0400, 
 Mike Stark <michael.e.stark@gsfc.nasa.gov> wrote:
>Don Harrison wrote:
>> 
>> Tucker Taft wrote:
>> 
><snip> 
>> :and little or no use of dynamic storage allocation after
>> :system startup.
>> :
>> :Eiffel's dependence on dynamic storage allocation and garbage
>> :collection basically rules it out for most (serious) safety-critical
>> :applications, despite all its admittedly nice invariants and assertions.
>> 
[snip heaps of stuff about the evils of dynamic memory allocation in
safety critical applications, and how to get around it in various
languages such as turning off the GC!!]

I can't help but think that the reason dynamic memory allocation got such
a bad rap in the first place was there was no GC in old languages. Turning
it off seems to me like a step backwards.

Absolute control of memory allocation has been seen as necisary in safety
critical systems because you need to be sure that you will never run out
of memory and never write things over each other. 

Dynamic memory allocation made proving this much harder, so the safety
people just banned it, and used the measurable decrease in failures as
proof. Kill dynamic memory in C and it becomes a hell of a lot more
reliable.

However, GC has changed the whole landscape a bit. I wonder if anyone has
tried to formally prove that a GC will ensure you never die from running
out of memory in a program with strictly controlled objects in a
controlled environment?

Programs are so complex today that doing safety analysis right from the
bottom (like where variables are allocated in memory) up for every program
is getting out of the question. At some point there is going to have to be
a heriachical aproach to safety, where low level tools (such as GC) are
proven safe first. Future programs can use these tools, and can have the
safety analysis done at a higher level without worrying about proving the
low level tools all over again.

I'm sure GC would improve safety, but I wouldn't want to try and convince
the safety people. Safety people are by nature, and probably necesity,
conservative people and will take a hell of a lot of convincing before
they will let you do anything the new way, even if it is safer.

I also wouldn't want to try and provide the proof :-)

ABO




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-11  0:00     ` Ted Velkoff
@ 1997-07-12  0:00       ` Ken Garlington
  1997-07-13  0:00         ` Jon S Anthony
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-12  0:00 UTC (permalink / raw)



Ted Velkoff wrote:
> 
> Ken Garlington wrote:
> 
> > I'm not sure what was in Ada83 that was omitted in Ada95; however, I have
> > noticed
> > that Eiffel examples posted in various places tend to have assertions that
> > are
> > fairly simple in nature (range checks), etc that are directly representable
> > in Ada.
> > Those that aren't tend to be easy to do with good Ada design using
> > exceptions (sort
> > of the same "good design principles" that you discussed using in Eiffel to
> > get
> > the features made explicit in Ada).
> >
> 
> There's a big difference between assertions and exceptions.
> 
> I think a sign that says: "Dangerous curve ahead: left turn required"
> (precondition)
> 
> is much more useful than one that says: "Accident zone ahead"
> (exception declaration)

However, compare and contrast:

(ada-ish): type Foo_Type is range 1 .. 10;
           procedure Do_Something ( X : in Foo_Type );

(Eiffel-ish): procedure Do_Something ( X : in Integer );
                require X > 0 and X < 11;

Doesn't seem to make a lot of difference to me, although of course I
get to reuse Foo_Type in a lot of static contexts.

As to the more elaborate checks:

       procedure Do_Something (X : in Integer);

       X_Error : exception;
         -- raised if X does not meet precondition Complex_Precondition;

is not particularly more difficult to understand than:

     procedure Do_Something (X: in Integer);
       require Complex_Precondition(X);

The key is to have the external view of these assertions documented, and
to have
violations of those assertions cause certain effects in the system. Ada
has done more
than an adequate job in this area for our safety-critical systems. I
don't
need more of this; I need more static analysis tools (as the Safety and
Security Annex provides the foundation to support) and more efficient
code,
since safety critical embedded systems usually have a lot of
requirements
that preclude using the latest and greatest hardware.


> 
> -- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-11  0:00   ` Don Harrison
  1997-07-11  0:00     ` James Graves
@ 1997-07-12  0:00     ` Ken Garlington
  1997-07-15  0:00       ` Don Harrison
  1997-07-16  0:00     ` Alan Brain
  2 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-12  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> If even this small overhead is unacceptable, you can force static binding
> where necessary by freezing routines.
> Although you forgo the flexibility of
> polymorphism, you can still take advantage of inheritance by virtue of Eiffel
> synonyms - these allow you to declare a routine under different names.

But I can do this in Ada, as well, so I don't see the benefit.

 :Does this "pre-allocated memory pool" mean that you will know exactly
> :what address
> :each object's data will reside at, or merely that you dynamically
> :allocate memory
> :at initialization and do not dynamically allocate after initialization
> :is complete?
> 
> The latter. You don't actually need to know *where* objects are allocated,
> merely that there is sufficient memory to allocate them.

Actually, in my systems, I do need to know where they are allocated, so
that
I can examine them from the hideously crude display in the cockpit
during
troubleshooting.

> Maybe general assertions are more common than you imagine. However, I agree
> that range constraints are roughly covered by Ada subtypes. I use them liberally
> for just that purpose.

Maybe, but again, I would like to see how these complex assertions are
used. Again,
the code I've seen to date doesn't seem to use them that much.

> Correct me I misunderstand you.. Are you wondering whether contracting
> helps you to identify more bugs? I can offer my own experience which has
> firmly convinced me of this.

Contracting definitely identifies more bugs. However, my concern with
Eiffel
assertions (and Ada assertions, for that matter) is that, once raised,
it's
not always clear what to do about them. In a safety-critical system such
as
we build, you can't just generate a core dump, or ask the user what to
do next.
You have to generate a correct response to the assertion failure, and
you have
to do it very quickly. Static assertion checks, of course, can be
detected and
corrected during development, which is why I like Ada's strong static
type checking.

There is a school of thought that says to add in assertions, test the
system, and
then remove/suppress the exceptions. I have seen too many cases of code
that works
with the assertions active, and then breaks (due to timing differences,
or more
likely code generation errors) to have much confidence in this approach.

Another consequence of using assertions is that you have to develop and
test the
assertions. As a result, you need confidence that the benefits of the
assertions
outweigh the dilution of your test effort. One of the advantages of
Ada's simpler
approach (at least, it seems simpler to me) to simple
pre/post-conditions (range
checks in particular) is that the cost of adding them is somewhat
reduced. However,
in both languages, overuse of assertions may be just as bad as underuse.

(As you can tell, I'm somewhat of an assertions heretic. However, I will
say that
for non-real-time, non-safety-critical systems, they are outstanding. My
tool code
is lousy with them.)

> Consequently, when we (a team of 5) recently
> reached the end of a 5 month long development effort of incremental coding
> and integration testing, the parts of the system that used contracting work
> flawlessly apart from problems resulting from misinterpretation of requirements.

Most of the problems we see in formal testing are from misinterpretation
of
requirements - which is another issue I have with assertions as a magic
safety wand.
Of course, Bertand Meyer's Eiffel website insists that even
misinterpretation of
requirements (Ariane V) will be a problem no longer when Eiffel is used!
:)




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-11  0:00   ` Kazimir Majorinc
@ 1997-07-12  0:00     ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-12  0:00 UTC (permalink / raw)



Kazimir Majorinc wrote:
> 
> Eiffel is not safe language. Look for example Shang's article
> Is a Cow an Animal? Somewhere on Net. Look at Ellipse CIrcle dilemma.
> Should array of superclass be superclass of array of subclass? Noone
> knows. Do you accept Liskov Substitution principle? Do you accept
> derivation from abstract classes only? Noone knows.  Eiffel's assertions
> are good, but it's like to drive motorcycle 250 km/hour and say that
> helmet will help you.
> 
> For some of us, OO is not only suspect, but even wrong paradigm. It's
> place is in laboratory, it is not good for mainstream programming, not
> to mention safety.
> 
> If you are interested primarily in safety, you should give up from OO, and
> choose good old procedural paradigm. It is not far less powerfull, but it
> is certenly safer. Ada 83 is maybe the best answer.

I'm not sure I'd call Ada 83 "procedural." SPC calls it "object-based".

My personal experience is that Ada 83 objects are much better for
handing
complex safety-critical systems than procedural objects in languages
like
FORTRAN and JOVIAL. For very simple systems, I suspect it doesn't
matter.

As to whether full OO languages like Ada 95 introduce safety issues...
we'll
see.

> 
> Regards,
> ______________________________________________________________
>         Kazimir Majorinc,  dipl. ing. of mathematics
>  Faculty of Natural Sciences and Math, Uni of Zagreb, Croatia
> mailto: kmajor@public.srce.hr    http://public.srce.hr/~kmajor
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-12  0:00       ` Ken Garlington
@ 1997-07-13  0:00         ` Jon S Anthony
  1997-07-14  0:00           ` Wes Groleau
                             ` (2 more replies)
  0 siblings, 3 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-13  0:00 UTC (permalink / raw)



In article <33C831CE.4E56@flash.net> Ken Garlington <keg0@flash.net> writes:

> However, compare and contrast:
> 
> (ada-ish): type Foo_Type is range 1 .. 10;
>            procedure Do_Something ( X : in Foo_Type );
> 
> (Eiffel-ish): procedure Do_Something ( X : in Integer );
>                 require X > 0 and X < 11;
> 
> Doesn't seem to make a lot of difference to me

That's because there basically isn't any.


>, although of course I get to reuse Foo_Type in a lot of static
> contexts.

Right.  But then that's what Eiffel class invariants are about...


> As to the more elaborate checks:
> 
>        procedure Do_Something (X : in Integer);
> 
>        X_Error : exception;
>          -- raised if X does not meet precondition Complex_Precondition;
> 
> is not particularly more difficult to understand than:
> 
>      procedure Do_Something (X: in Integer);
>        require Complex_Precondition(X);

The complexity of the pre/post condition is not an issue.  You can get
basically the same "expressiveness" in Ada with:

    type Require is boolean range True..True;
...

    Assert : Require := Complex_Precondition(X);

So, the complexity of the condition is irrelevant.  What you can't get
at this level of expressiveness are general level class invariants.
BUT,


> The key is to have the external view of these assertions documented,
> and to have violations of those assertions cause certain effects in
> the system. Ada has done more than an adequate job in this area for
> our safety-critical systems. I don't need more of this; I need more
> static analysis tools (as the Safety and Security Annex provides the
> foundation to support) and more efficient code, since safety
> critical embedded systems usually have a lot of requirements that
> preclude using the latest and greatest hardware.

sounds a _lot_ more apropos and important.

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-11  0:00     ` Donovan Baarda
@ 1997-07-13  0:00       ` Steve Furlong
  1997-07-16  0:00         ` Joachim Durchholz
  0 siblings, 1 reply; 255+ messages in thread
From: Steve Furlong @ 1997-07-13  0:00 UTC (permalink / raw)



In article <slrn5scda9.3bm.abo@minkirri.apana.org.au>,
Donovan Baarda <abo@minkirri.apana.org.au> wrote:
>[snip heaps of stuff about the evils of dynamic memory allocation in
>safety critical applications, and how to get around it in various
>languages such as turning off the GC!!]
>
>I can't help but think that the reason dynamic memory allocation got such
>a bad rap in the first place was there was no GC in old languages. Turning
>it off seems to me like a step backwards.
>
>Absolute control of memory allocation has been seen as necisary in safety
>critical systems because you need to be sure that you will never run out
>of memory and never write things over each other. 
...

Another reason GC wasn't or isn't used in hard-real-time systems is
because you could never tell when it was going to need a long time to
get or free memory. If your process _must_ check ports every 10 ms,
you can't be waiting half a second for memory compaction.

Modern GC presumably can get around that problem, but the purveyors
presumably can't prove its efficacy and response time to the
satisfaction of the FAA and other safety hard-noses.


Regards,
Steve Furlong




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-11  0:00     ` James Graves
@ 1997-07-14  0:00       ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-14  0:00 UTC (permalink / raw)



James Graves writes:

:In article <ED5AGp.5MJ@syd.csa.com.au>,
:Don Harrison <donh@syd.csa.com.au> wrote:
:>
:> I suspect that you can also make an Eiffel reference access a statically
:> allocated object (expanded type) using a standard class (MEMORY? someone may 
:> wish to confirm this). There would certainly be no technical obstacle to 
:> providing this capability if it doesn't already exist enabling you to 
:> statically allocate whatever memory you require if that's what you want 
:> (as in your application domain). 
:>
:
:You are not allowed to make a reference to an expanded object in Eiffel,
:because of the information hiding principal.  To be able to diddle with
:another object's internal data could easily violate the class
:invariant.

Oops! Quite true. 

I agree the technique you suggest is better.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-13  0:00         ` Jon S Anthony
@ 1997-07-14  0:00           ` Wes Groleau
  1997-07-15  0:00             ` Jon S Anthony
  1997-07-15  0:00           ` Don Harrison
  1997-07-16  0:00           ` Paul Johnson
  2 siblings, 1 reply; 255+ messages in thread
From: Wes Groleau @ 1997-07-14  0:00 UTC (permalink / raw)



> > As to the more elaborate checks:
> >
> >        procedure Do_Something (X : in Integer);
> >
> >        X_Error : exception;
> >          -- raised if X does not meet precondition Complex_Precondition;
> >
> > is not particularly more difficult to understand than:
> >
> >      procedure Do_Something (X: in Integer);
> >        require Complex_Precondition(X);
> 
> The complexity of the pre/post condition is not an issue.  You can get
> basically the same "expressiveness" in Ada with:
> 
>     type Require is boolean range True..True;
> ...
> 
>     Assert : Require := Complex_Precondition(X);

Although this raises Constraint_Error instead of X_Error, i.e., it is
a little less descriptive

-- 
----------------------------------------------------------------------
    Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA
Senior Software Engineer - AFATDS                  Tool-smith Wanna-be

Don't send advertisements to this domain unless asked!  All disk space
on fw.hac.com hosts belongs to either Hughes Defense Communications or 
the United States government.  Using email to store YOUR advertising 
on them is trespassing!
----------------------------------------------------------------------




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-11  0:00     ` Robert S. White
@ 1997-07-15  0:00       ` Don Harrison
  1997-07-15  0:00         ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-15  0:00 UTC (permalink / raw)



Robert S. White wrote:

:In article <gwinn-1007971853320001@dh5152077.res.ray.com>, gwinn@res.ray.com 
:says...
:   ...snip...
:>However, there was a lot more to it than to say it was Ada:  We were
:>required to use a special safety-critical-code subset of Ada, which was
:>*sharply* smaller than Ada83.  (I no longer recall the details, but I
:>could dig them up, given a week or three.  It seems to me that it was a
:>commercial product.)
:>
:>Perhaps aside from the strong typing, it was not clear just what was left
:>that was particular to Ada, or why one couldn't do the same radical
:>simplification to any language one might choose, to much the same effect.
:>
:>So, I don't know that I buy the theory that Ada83 or Ada95 is the only
:>choice for safety-critical systems, as what survives isn't really either
:>language, and one can do the same surgery on any reasonable language. 
:   ...snip...
:
:  Sorry Joe I do not agree!  

Well, you're both right. Joe is right is saying that when you strip out (read 
don't use) the powerful features of languages for safety-critical applications,
they start to look the same. You're also right in saying that what's left over
become the distinguishing features.

:Even if you strip down Ada 83 to a small
:subset you still benefit from a lot of the design requirements 
:that went into the language.  

Even more so with Eiffel because you're still have, among other things, the 
reliability/reuse enhancing facilities of:

  - Built-in, general purpose, inheritable contracts.
  - A rigorous, fine-grained encapsulation model.


:  I have been implementing software solutions in industry since 1978 
:so I think I qualify as an equal curmudgeon to yourself as far is to
:what works and what does not work.  No silver bullets, although a good
:problem domain understanding, actual software _design_ with peer 
:reviews, and software inspections with checklists, and finally
:low level whitebox software module tests (along with final qual
:tests to requirements) work best for safety-critical software.  Ada is
:still an aid, IMO for the end safety-critical objective.  Eiffel has 
:yet to prove its advantages to me.

All these things are good. Adding Design by Contract to them helps you even more.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-13  0:00         ` Jon S Anthony
  1997-07-14  0:00           ` Wes Groleau
@ 1997-07-15  0:00           ` Don Harrison
  1997-07-15  0:00             ` Ken Garlington
  1997-07-16  0:00           ` Paul Johnson
  2 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-15  0:00 UTC (permalink / raw)



Jon S Anthony wrote:

:In article <33C831CE.4E56@flash.net> Ken Garlington <keg0@flash.net> writes:
:
:> However, compare and contrast:
:> 
:> (ada-ish): type Foo_Type is range 1 .. 10;
:>            procedure Do_Something ( X : in Foo_Type );
:> 
:> (Eiffel-ish): procedure Do_Something ( X : in Integer );
:>                 require X > 0 and X < 11;
:> 
:> Doesn't seem to make a lot of difference to me
:
:That's because there basically isn't any.

In this case, only by virtue of the fact that in Ada, Integer isn't an extensible 
type. Even if it were, you can't inherit the contract. You have to redeclare 
it each time you inherit - not very good for maintenance, let alone reliability. 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-12  0:00     ` Ken Garlington
@ 1997-07-15  0:00       ` Don Harrison
  1997-07-15  0:00         ` Wes Groleau
                           ` (2 more replies)
  0 siblings, 3 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-15  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> If even this small overhead is unacceptable, you can force static binding
:> where necessary by freezing routines.
:> Although you forgo the flexibility of
:> polymorphism, you can still take advantage of inheritance by virtue of Eiffel
:> synonyms - these allow you to declare a routine under different names.
:
:But I can do this in Ada, as well, so I don't see the benefit.

I'm not saying there is any extra benefit - merely that you don't have to 
wear the overhead of dynamic binding if you're desperate to maximise efficiency.
Tucker mentioned that overhead. I'm saying it isn't an issue.

BTW, how do call a procedure under different names in Ada?


: :Does this "pre-allocated memory pool" mean that you will know exactly
:> :what address
:> :each object's data will reside at, or merely that you dynamically
:> :allocate memory
:> :at initialization and do not dynamically allocate after initialization
:> :is complete?
:> 
:> The latter. You don't actually need to know *where* objects are allocated,
:> merely that there is sufficient memory to allocate them.
:
:Actually, in my systems, I do need to know where they are allocated, so
:that
:I can examine them from the hideously crude display in the cockpit
:during
:troubleshooting.

That *is* hideously crude (and brings back some bad memories). Depending on how
crude you mean, maybe a primitive tool could give you a map of where objects get 
put in memory. If you mean incredibly crude, use non-reference (expanded in 
Eiffel) types and use a linker-generated memory map.


:> Maybe general assertions are more common than you imagine. However, I agree
:> that range constraints are roughly covered by Ada subtypes. I use them liberally
:> for just that purpose.
:
:Maybe, but again, I would like to see how these complex assertions are
:used. 

You would use them anywhere that a piece of code makes assumptions. For example,
to help avoid the Ariane fiasco, include contracts in the INS(?) that specify 
Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
you apply Ariane 5 dynamics to it.

:Again, the code I've seen to date doesn't seem to use them that much.

If you're looking in Ada code, you're looking in the wrong place because few
Ada developers recognise there are additional benefits from using them in 
addition to static typing and the predefined contracts already in Ada 
(the conditions under which predefined exceptions - eg. Constraint_Error - 
are raised).

Static typing gives you static contract checking. Assertions (predefined and
user-defined give you dynamic contract checking *during development*. What 
most Ada software engineers miss out on is the user-defined variety which 
bring a non-trivial benefit to reliability and reuse.


:> Correct me I misunderstand you.. Are you wondering whether contracting
:> helps you to identify more bugs? I can offer my own experience which has
:> firmly convinced me of this.
:
:Contracting definitely identifies more bugs. However, my concern with
:Eiffel
:assertions (and Ada assertions, for that matter) is that, once raised,
:it's
:not always clear what to do about them. 

They are only turned on during development, so what you do is fix the underlying
problem which is usually not difficult to find if you've used them systematically.
Even if you haven't (I was the only one of a team of 5 using them in our recent
development cycle), they still tell you more than you would otherwise be told.

Good design complemented by static typing and Design by Contract is unbeatable, 
IME.


:In a safety-critical system such
:as
:we build, you can't just generate a core dump, or ask the user what to
:do next.
:You have to generate a correct response to the assertion failure, and
:you have
:to do it very quickly. 

Right. However, only an incorrect program will raise assertion violations at
runtime. As you systematically identify and fix the errors causing them during
development, you can turn assertions off with confidence when the system 
goes live. Then, any errors you may have missed will be handled by exception
handlers in the usual way.
 
:Static assertion checks, of course, can be
:detected and
:corrected during development, which is why I like Ada's strong static
:type checking.

I agree completely. Static typing is great but it isn't the *whole* story.


:There is a school of thought that says to add in assertions, test the
:system, and
:then remove/suppress the exceptions. I have seen too many cases of code
:that works
:with the assertions active, and then breaks (due to timing differences,

Yes, timing *is* something to be concerned about when applied to realtime 
systems. That's why I suggested not using assertions in the hard realtime
threads of a process. BTW, software designed using DBC may actually run *faster*
than code without it because you get to strip out all the defensive validity
checks. You have already ascertained during development that operations are
called in valid contexts so you don't have to check the context.

:or more
:likely code generation errors) to have much confidence in this approach.

If that's a problem, you need to get your vendor to clean their act up.


:Another consequence of using assertions is that you have to develop and
:test the
:assertions. 

Correct. My initial reaction when I started using them was "Gee, I've got to
do this extra work on top of writing the "real" code! However, I found I was 
spending about a third of the time integrating compared with my colleagues
which meant I was saving time overall and producing more reliable code to boot.


:As a result, you need confidence that the benefits of the
:assertions
:outweigh the dilution of your test effort. 

IME, they do.

:One of the advantages of
:Ada's simpler
:approach (at least, it seems simpler to me) to simple
:pre/post-conditions (range
:checks in particular) is that the cost of adding them is somewhat
:reduced. 

I disagree. It takes me about the same amount of time to specify an Ada
subtype as it does to specify a more general assertion. Even if the general 
assertion is a function, I would more than likely need to write it anyway so
would have expended the effort anyway.


:However,
:in both languages, overuse of assertions may be just as bad as underuse.

It is possible to overuse them but 99% of developers err on the othger side. :)


:(As you can tell, I'm somewhat of an assertions heretic. 

That's fine but have a go at using them where appropriate. I'm sure you'll 
become convinced.

:However, I will
:say that
:for non-real-time, non-safety-critical systems, they are outstanding. My
:tool code
:is lousy with them.)
:
:> Consequently, when we (a team of 5) recently
:> reached the end of a 5 month long development effort of incremental coding
:> and integration testing, the parts of the system that used contracting work
:> flawlessly apart from problems resulting from misinterpretation of requirements.
:
:Most of the problems we see in formal testing are from misinterpretation
:of
:requirements - which is another issue I have with assertions as a magic
:safety wand.

No use of assertions will stop you misinterpreting requirements. They're not 
a magic wand but they *will* help you remove a class of errors you would 
otherwise miss.


:Of course, Bertand Meyer's Eiffel website insists that even
:misinterpretation of
:requirements (Ariane V) will be a problem no longer when Eiffel is used!

Come on. He's not saying that.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-14  0:00           ` Wes Groleau
@ 1997-07-15  0:00             ` Jon S Anthony
  0 siblings, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-15  0:00 UTC (permalink / raw)





Don Sez:

> Jon S Anthony wrote:
> 
> :In article <33C831CE.4E56@flash.net> Ken Garlington <keg0@flash.net> writes:
> :
> :> However, compare and contrast:
> :> 
> :> (ada-ish): type Foo_Type is range 1 .. 10;
> :>            procedure Do_Something ( X : in Foo_Type );
> :> 
> :> (Eiffel-ish): procedure Do_Something ( X : in Integer );
> :>                 require X > 0 and X < 11;
> :> 
> :> Doesn't seem to make a lot of difference to me
> :
> :That's because there basically isn't any.
> 
> In this case, only by virtue of the fact that in Ada, Integer isn't
> an extensible type.

First, Integer _is_ extensible with respect to operations.  You can't
add new slots to it (data extension), but you can add operations.  But
then why would you _want_ to add new slots??

Second, even if you couldn't do this, why would that "fact" be a
reason for the claim??


> Even if it were, you can't inherit the contract.

Well, a) it is and b) you certainly _can_ inherity this sort of
contract:

    type My_Integer is new Integer range 1..10;
    --
    -- Inherits std integer ops and attributes
    -- Maybe we add some more to these specific to My_Integer

... Somewhere later

    type Gain_Type is new My_Integer;
    --
    -- Inherits the range constraint and all My_Integer ops,
    -- both the std integer ones and any of the new specific ones
    -- Override or add new ones here...


> You have to redeclare it each time you inherit 

I don't think so.


/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00       ` Don Harrison
@ 1997-07-15  0:00         ` Wes Groleau
  1997-07-15  0:00           ` Ken Garlington
                             ` (2 more replies)
  1997-07-15  0:00         ` Ken Garlington
  1997-07-16  0:00         ` Warwick Pulley
  2 siblings, 3 replies; 255+ messages in thread
From: Wes Groleau @ 1997-07-15  0:00 UTC (permalink / raw)



> You would use them anywhere that a piece of code makes assumptions. For example,
> to help avoid the Ariane fiasco, include contracts in the INS(?) that specify
> Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
> you apply Ariane 5 dynamics to it.

Here we go again with this myth.  Probably won't help, but I'll say 
one more time what others said over and over: telling people to 
assert or document everything pertinent will NOT cure the failure 
to recognize what's pertinent!!  Or in your own words:

> No use of assertions will stop you misinterpreting requirements. 

-- 
----------------------------------------------------------------------
    Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA
Senior Software Engineer - AFATDS                  Tool-smith Wanna-be

Don't send advertisements to this domain unless asked!  All disk space
on fw.hac.com hosts belongs to either Hughes Defense Communications or 
the United States government.  Using email to store YOUR advertising 
on them is trespassing!
----------------------------------------------------------------------




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00       ` Don Harrison
@ 1997-07-15  0:00         ` Ken Garlington
  1997-07-16  0:00           ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-15  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Robert S. White wrote:
> 
> :In article <gwinn-1007971853320001@dh5152077.res.ray.com>, gwinn@res.ray.com
> :says...
> :   ...snip...
> :>However, there was a lot more to it than to say it was Ada:  We were
> :>required to use a special safety-critical-code subset of Ada, which was
> :>*sharply* smaller than Ada83.  (I no longer recall the details, but I
> :>could dig them up, given a week or three.  It seems to me that it was a
> :>commercial product.)
> :>
> :>Perhaps aside from the strong typing, it was not clear just what was left
> :>that was particular to Ada, or why one couldn't do the same radical
> :>simplification to any language one might choose, to much the same effect.
> :>
> :>So, I don't know that I buy the theory that Ada83 or Ada95 is the only
> :>choice for safety-critical systems, as what survives isn't really either
> :>language, and one can do the same surgery on any reasonable language.
> :   ...snip...
> :
> :  Sorry Joe I do not agree!
> 
> Well, you're both right. Joe is right is saying that when you strip out (read
> don't use) the powerful features of languages for safety-critical applications,
> they start to look the same. You're also right in saying that what's left over
> become the distinguishing features.
> 
> :Even if you strip down Ada 83 to a small
> :subset you still benefit from a lot of the design requirements
> :that went into the language.
> 
> Even more so with Eiffel because you're still have, among other things, the
> reliability/reuse enhancing facilities of:
> 
>   - Built-in, general purpose, inheritable contracts.
>   - A rigorous, fine-grained encapsulation model.

Actually, some of the Eiffel inheritance got stripped out in a previous
post,
as I recall. What was left of Eiffel looked a lot like Ada.

> 
> :  I have been implementing software solutions in industry since 1978
> :so I think I qualify as an equal curmudgeon to yourself as far is to
> :what works and what does not work.

I hate BS statements like this!

The thread clearly states, "Safety-critical development". Do you do
safety-critical systems in Eiffel? If so, please describe these systems.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00           ` Don Harrison
@ 1997-07-15  0:00             ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-15  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Jon S Anthony wrote:
> 
> :In article <33C831CE.4E56@flash.net> Ken Garlington <keg0@flash.net> writes:
> :
> :> However, compare and contrast:
> :>
> :> (ada-ish): type Foo_Type is range 1 .. 10;
> :>            procedure Do_Something ( X : in Foo_Type );
> :>
> :> (Eiffel-ish): procedure Do_Something ( X : in Integer );
> :>                 require X > 0 and X < 11;
> :>
> :> Doesn't seem to make a lot of difference to me
> :
> :That's because there basically isn't any.
> 
> In this case, only by virtue of the fact that in Ada, Integer isn't an extensible
> type. Even if it were, you can't inherit the contract. You have to redeclare
> it each time you inherit - not very good for maintenance, let alone reliability.

Not sure what this means... the "Integer" referred to above would be
Eiffel's integer,
not Ada's.

You can certainly inherit the contract for Foo_Type in Ada. Any types
declared based on
Foo_Type will inherit the operations defined for it. (Apparently this
isn't used a whole
lot, but it is available...)


> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00       ` Don Harrison
  1997-07-15  0:00         ` Wes Groleau
@ 1997-07-15  0:00         ` Ken Garlington
  1997-07-16  0:00           ` Jean-Marc Jezequel
                             ` (2 more replies)
  1997-07-16  0:00         ` Warwick Pulley
  2 siblings, 3 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-15  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :Don Harrison wrote:
> :>
> :> If even this small overhead is unacceptable, you can force static binding
> :> where necessary by freezing routines.
> :> Although you forgo the flexibility of
> :> polymorphism, you can still take advantage of inheritance by virtue of Eiffel
> :> synonyms - these allow you to declare a routine under different names.
> :
> :But I can do this in Ada, as well, so I don't see the benefit.
> 
> I'm not saying there is any extra benefit - merely that you don't have to
> wear the overhead of dynamic binding if you're desperate to maximise efficiency.
> Tucker mentioned that overhead. I'm saying it isn't an issue.

But you also said that it was required to use that part of Eiffel
inheritance not
available in Ada. In this statement, you seem to be saying that if I
want an
efficient safety-critical system (which I always do), I have to give us
some of
that extra inheritance. Do I need the full Eiffel inheritance model, or
don't I?

> 
> BTW, how do call a procedure under different names in Ada?

Via the "rename" statement.

> 
> : :Does this "pre-allocated memory pool" mean that you will know exactly
> :> :what address
> :> :each object's data will reside at, or merely that you dynamically
> :> :allocate memory
> :> :at initialization and do not dynamically allocate after initialization
> :> :is complete?
> :>
> :> The latter. You don't actually need to know *where* objects are allocated,
> :> merely that there is sufficient memory to allocate them.
> :
> :Actually, in my systems, I do need to know where they are allocated, so
> :that
> :I can examine them from the hideously crude display in the cockpit
> :during
> :troubleshooting.
> 
> That *is* hideously crude (and brings back some bad memories). Depending on how
> crude you mean, maybe a primitive tool could give you a map of where objects get
> put in memory. If you mean incredibly crude, use non-reference (expanded in
> Eiffel) types and use a linker-generated memory map.

Both approaches require that the memory address be known before
execution time,
however, so I still care where objects are located. I also care for
other reasons,
such as memory-mapped I/O, of course.

> 
> :> Maybe general assertions are more common than you imagine. However, I agree
> :> that range constraints are roughly covered by Ada subtypes. I use them liberally
> :> for just that purpose.
> :
> :Maybe, but again, I would like to see how these complex assertions are
> :used.
> 
> You would use them anywhere that a piece of code makes assumptions. For example,
> to help avoid the Ariane fiasco, include contracts in the INS(?) that specify
> Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
> you apply Ariane 5 dynamics to it.

This is why my blood pressure goes up!

The _Ada_ implementation did generate an assertion violation the very
first time
Ariane 5 dynamics were applied to it. Unfortunately, the very first time
Ariane 5
dynamics were applied to it was at LANUCH!

They were not applied earlier, because the contractor assumed that the
Ariane 5
dynamics were the same as the Ariane 4, so why spend the money testing
to the same
conditions already tested earlier? (They were wrong, of course, but they
didn't know
that at the time).

The other part of the problem was that the _response_ to the assertion
violation was
wrong. The designer assumed the assertion would occur due to a hardware
failure, not
a software requirements failure, and so the handler shut down the
"offending" hardware,
rather than attempting some other action (e.g. replacing the
out-of-range value with
a "safe" value). Frankly, I don't know that I would have written the
handler differently
myself.

This is all clearly documented in the final report, available on the
Web.

According to Meyer, et. al. Eiffel programmers would have written the
handler
differently, and also they would have known to do the testing
differently (even though
the requirements specification said that the tests need not change).
However, their
explanation as to why this is true is far from convincing (basically,
that "Eiffel
programmers believe in quality" or some such nonsense). Their "analysis"
is also
on the Web. I've asked them to post my rebuttal to their paper, but I
don't know
if they ever did.

This is why I dislike people with no background in safety-critical
flight systems discussing
such issues. They believe that "software is software." and apply the
expertise in their
domain to mine. They usually do about as good a job as when I try to
discuss compiler
design :)

> 
> :Again, the code I've seen to date doesn't seem to use them that much.
> 
> If you're looking in Ada code, you're looking in the wrong place because few
> Ada developers recognise there are additional benefits from using them in
> addition to static typing and the predefined contracts already in Ada
> (the conditions under which predefined exceptions - eg. Constraint_Error -
> are raised).

No - I'm looking at Eiffel code. (Why would I look at Ada code to
determine how
Eiffel is used?)

> Static typing gives you static contract checking. Assertions (predefined and
> user-defined give you dynamic contract checking *during development*. What
> most Ada software engineers miss out on is the user-defined variety which
> bring a non-trivial benefit to reliability and reuse.

Not this Ada engineer! I have dynamic assertions all over the place in
my
tools!

My problem, again, is in the fundamental nature of dynamic assertions
for safety-critical
embedded systems, which have some unique risks, whether you (a) leave
them in after
development, or (b) take them out after developmental testing, but
before usage.

> 
> :> Correct me I misunderstand you.. Are you wondering whether contracting
> :> helps you to identify more bugs? I can offer my own experience which has
> :> firmly convinced me of this.
> :
> :Contracting definitely identifies more bugs. However, my concern with
> :Eiffel
> :assertions (and Ada assertions, for that matter) is that, once raised,
> :it's
> :not always clear what to do about them.
> 
> They are only turned on during development, so what you do is fix the underlying
> problem which is usually not difficult to find if you've used them systematically.
> Even if you haven't (I was the only one of a team of 5 using them in our recent
> development cycle), they still tell you more than you would otherwise be told.

I am aware of at least one project developing an embedded missile
controller,
that did exactly what you describe (in Ada). Here's what happened:

1. Their timings changed, which introduced some subtle differences in
the
relationships between tasks and external interrupts. Some of these
subtle
differences invalidated their original testing.

2. Their object code changed (obviously), which required reanalysis of
their
object-code branch coverage.

3. At least one compiler bug was introduced, which was definitely
unsettling.

What safety-critical system did you develop where you turned off
assertions
afer development? What standard (DO-178?) did you use for certification?

The other prong of this is that, while assertions are keen for catching
design problems, I haven't seen much evidence that they catch high-level
requirements problems (not surprising, since the code was presumably
written
to match the requirements). In 13 years of developing safety-critical
embedded systems, our process tends to handle design problems fairly
early.
It's those high-level requirements problems where we need the most help.

> 
> Good design complemented by static typing and Design by Contract is unbeatable,
> IME.
> 
> :In a safety-critical system such
> :as
> :we build, you can't just generate a core dump, or ask the user what to
> :do next.
> :You have to generate a correct response to the assertion failure, and
> :you have
> :to do it very quickly.
> 
> Right. However, only an incorrect program will raise assertion violations at
> runtime. As you systematically identify and fix the errors causing them during
> development, you can turn assertions off with confidence when the system
> goes live. Then, any errors you may have missed will be handled by exception
> handlers in the usual way.
> 
> :Static assertion checks, of course, can be
> :detected and
> :corrected during development, which is why I like Ada's strong static
> :type checking.
> 
> I agree completely. Static typing is great but it isn't the *whole* story.
> 
> :There is a school of thought that says to add in assertions, test the
> :system, and
> :then remove/suppress the exceptions. I have seen too many cases of code
> :that works
> :with the assertions active, and then breaks (due to timing differences,
> 
> Yes, timing *is* something to be concerned about when applied to realtime
> systems. That's why I suggested not using assertions in the hard realtime
> threads of a process. BTW, software designed using DBC may actually run *faster*
> than code without it because you get to strip out all the defensive validity
> checks. You have already ascertained during development that operations are
> called in valid contexts so you don't have to check the context.

But almost all of our safety-critical threads are hard realtime threads!
That's a HUGE limitation for our systems!

> 
> :or more
> :likely code generation errors) to have much confidence in this approach.
> 
> If that's a problem, you need to get your vendor to clean their act up.

Easier said than done! :)

What is the process to certify Eiffel compilers as being acceptably
mature
(code generation-wise) for safety-critical systems? Is all testing
performed
with assertions on and assertions off in all test cases?

> 
> :Another consequence of using assertions is that you have to develop and
> :test the
> :assertions.
> 
> Correct. My initial reaction when I started using them was "Gee, I've got to
> do this extra work on top of writing the "real" code! However, I found I was
> spending about a third of the time integrating compared with my colleagues
> which meant I was saving time overall and producing more reliable code to boot.
> 
> :As a result, you need confidence that the benefits of the
> :assertions
> :outweigh the dilution of your test effort.
> 
> IME, they do.

However, it sounds like you're talking about a non-safety-critical
system, and
certainly not a hard real-time embedded safety-critical systems. In that
case,
I agree. For tools, simulations, etc. I would use all of the assertions
I could.

However, what about the topic of this thread (safety-critical systems)?
It sounds
like there's a lot of limitations as to using (and inheriting)
assertions for
this environment.

> 
> :One of the advantages of
> :Ada's simpler
> :approach (at least, it seems simpler to me) to simple
> :pre/post-conditions (range
> :checks in particular) is that the cost of adding them is somewhat
> :reduced.
> 
> I disagree. It takes me about the same amount of time to specify an Ada
> subtype as it does to specify a more general assertion. Even if the general
> assertion is a function, I would more than likely need to write it anyway so
> would have expended the effort anyway.
> 
> :However,
> :in both languages, overuse of assertions may be just as bad as underuse.
> 
> It is possible to overuse them but 99% of developers err on the othger side. :)
> 
> :(As you can tell, I'm somewhat of an assertions heretic.
> 
> That's fine but have a go at using them where appropriate. I'm sure you'll
> become convinced.
> 
> :However, I will
> :say that
> :for non-real-time, non-safety-critical systems, they are outstanding. My
> :tool code
> :is lousy with them.)
> :
> :> Consequently, when we (a team of 5) recently
> :> reached the end of a 5 month long development effort of incremental coding
> :> and integration testing, the parts of the system that used contracting work
> :> flawlessly apart from problems resulting from misinterpretation of requirements.
> :
> :Most of the problems we see in formal testing are from misinterpretation
> :of
> :requirements - which is another issue I have with assertions as a magic
> :safety wand.
> 
> No use of assertions will stop you misinterpreting requirements. They're not
> a magic wand but they *will* help you remove a class of errors you would
> otherwise miss.
> 
> :Of course, Bertand Meyer's Eiffel website insists that even
> :misinterpretation of
> :requirements (Ariane V) will be a problem no longer when Eiffel is used!
> 
> Come on. He's not saying that.

Read his analysis of Ariane V. He says _exactly_ that, and has defended
saying that in multiple newsgroups. A smart person, but not someone
who knows my domain particularly well.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00         ` Wes Groleau
@ 1997-07-15  0:00           ` Ken Garlington
  1997-07-16  0:00           ` Don Harrison
  1997-07-18  0:00           ` Robert I. Eachus
  2 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-15  0:00 UTC (permalink / raw)



Wes Groleau wrote:
> 
> > You would use them anywhere that a piece of code makes assumptions. For example,
> > to help avoid the Ariane fiasco, include contracts in the INS(?) that specify
> > Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
> > you apply Ariane 5 dynamics to it.
> 
> Here we go again with this myth.  Probably won't help, but I'll say
> one more time what others said over and over: telling people to
> assert or document everything pertinent will NOT cure the failure
> to recognize what's pertinent!!  Or in your own words:
> 
> > No use of assertions will stop you misinterpreting requirements.

Give it up. Until the end of time, Eiffel advocates will be using this
example showing why DBC/Eiffel is better than Ada. If some of the Ada
heavyweights had put up a fuss (a letter to IEEE, for example), we could
have nipped this in the bud. However, it's too late now.

> 
> --
> ----------------------------------------------------------------------
>     Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA
> Senior Software Engineer - AFATDS                  Tool-smith Wanna-be
> 
> Don't send advertisements to this domain unless asked!  All disk space
> on fw.hac.com hosts belongs to either Hughes Defense Communications or
> the United States government.  Using email to store YOUR advertising
> on them is trespassing!
> ----------------------------------------------------------------------




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-13  0:00       ` Steve Furlong
@ 1997-07-16  0:00         ` Joachim Durchholz
  1997-07-17  0:00           ` Ken Garlington
                             ` (3 more replies)
  0 siblings, 4 replies; 255+ messages in thread
From: Joachim Durchholz @ 1997-07-16  0:00 UTC (permalink / raw)



Steve Furlong wrote:
> get or free memory. If your process _must_ check ports every 10 ms,
> you can't be waiting half a second for memory compaction.

Arrgh! Will that idea nevere go away!!
The best available GC algorithms don't go away for compacting; they run
in parallel with the normal program (as a coroutine if you don't want a
preemptive scheduler).

> Modern GC presumably can get around that problem,

That reads "definitely", not "presumably". The algorithms are there.
Besides, hand-crafted GC may look nice on paper, but it's usually less
efficient than automatec GC.
Manual deallocation means programmers will pass around more copies of
objects, defeating the very reason why automated GC isn't used. (The
reason is that, if the programmer would just pass the reference, the
owner of the object has to worry wether that reference he gave aways is
still in use somewhere. If the object is copied, the owner can
deallocate the original and doesn't have to worry about the copy - but
the copying process itself may be more machine cycles than what would
have been necessary to reclaim the single object with automated GC.)


> but the purveyors
> presumably can't prove its efficacy and response time to the
> satisfaction of the FAA and other safety hard-noses.

Well, I'm feeling cynical today, so I'd say that the safety gurus just
don't know or care about the algorithms, because it's something new and
they'd have to *think*. (There is a surprising number of non-engineers
in any bureaucratic body.)

Regards,
Joachim
-- 
Please don't send unsolicited ads.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00         ` Wes Groleau
  1997-07-15  0:00           ` Ken Garlington
@ 1997-07-16  0:00           ` Don Harrison
  1997-07-16  0:00             ` Ken Garlington
  1997-07-18  0:00           ` Robert I. Eachus
  2 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-16  0:00 UTC (permalink / raw)



Inserted here is the original context of my statement: general assertions...

:> Maybe general assertions are more common than you imagine. However, I agree
:> that range constraints are roughly covered by Ada subtypes. I use them liberally
:> for just that purpose.
:
:Maybe, but again, I would like to see how these complex assertions are
:used. 

Wes Groleau wrote:

:> You would use them anywhere that a piece of code makes assumptions. For example,
:> to help avoid the Ariane fiasco, include contracts in the INS(?) that specify
:> Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
:> you apply Ariane 5 dynamics to it.
:
:Here we go again with this myth.  Probably won't help, but I'll say 
:one more time what others said over and over: telling people to 
:assert or document everything pertinent will NOT cure the failure 
:to recognize what's pertinent!!  

If you read carefully what I wrote in the context that I wrote it, you'll notice 
I'm not suggesting it will. I'm simply giving an *example* of a general 
assertion. Nowhere in my statement will you find any suggestion that you can 
formulate an assertion reflecting an assumption if you haven't first identified 
the assumption. No friend of logic would claim anything so outrageous.


So, just to make this clearer, what are the steps involved in proper use of 
contracting? They are:

1) Identify the assumptions.
2) Code the assumptions as assertions.
3) Validate that the coded assertions are always satisfied (and by implication,
   the assumptions they represent) by performing rigorous testing.

Note that each step depends on the previous one. No Eiffel software engineer
will tell you otherwise. There was a high degree of miscommunication during
the interminable "Ariane" thread, so it's not surprising that you were left
thinking that some believed the myth you describe.

FWIW, some participants in that thread were a little naive, IMO, in regarding
the Ariane article as a technical document. Its lack of *detailed* technical
content readily eliminates such an interpretation and exposes it as a marketing 
tool. IMO, some of the comments made in it were at best misleading or expressed
unsubstantiated (albeit valid) opinion. For the document to have any technical
credibility, it would need to be more in-depth, IMO. If you take the trouble to 
read any of Bertrand Meyer's technical papers, you will agree this was not 
one of them.


Now, having dealt with what I didn't mean by the quoted statement, :( 
can we get on to what I *did* mean? 

I've already said I was giving an example of a general assertion in the Ariane situation. Implied is the fact that they would have to be used in conjunction 
with established software engineering practice. 
 
What I *didn't* say but will say now is that using Design by Contract (read 
*disciplined* use of assertions) to complement testing will not only identify 
more errors but make them more obvious. More than likely the Ariane bug would
have been picked up by traditional means (since it's fairly obvious) but in 
the event that it wasn't, it would certainly have been identified if 
the assumption was identified and coded as an assertion.

:Or in your own words:
:
:> No use of assertions will stop you misinterpreting requirements. 

True, though irrelevant to the point I wasn't making. :)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00         ` Ken Garlington
@ 1997-07-16  0:00           ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-16  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:I hate BS statements like this!

Wow! I'm glad I didn't say it then! - it was Robert White. :)

As for your other comments, I hope to respond tomorrow. In the meantime, 
take a sedative. 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00           ` Don Harrison
@ 1997-07-16  0:00             ` Ken Garlington
  1997-07-16  0:00               ` Robert Dewar
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-16  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> More than likely the Ariane bug would
> have been picked up by traditional means (since it's fairly obvious) but in
> the event that it wasn't, it would certainly have been identified if
> the assumption was identified and coded as an assertion.

...and the same traditional means (testing to the actual Ariane V data)
were used to test the system (otherwise the assertion would never have
been exercised). Thus:

1. If the assertion was not identified and coded as an assertion, but
traditional means were used, the problem would have been discovered.

2. If the assertion had been identified and coded as an assertion, but
traditional means were NOT used, the problem would NOT have been
discovered.

So, since traditional methods were required anyway, how did adding the
assertion (either the Ada "Operand_Error" or your Eiffel equivalent)
help for this example?

Meyer et. al. argues that, if the system was written in Eiffel, that
the assertion would have been added despite the lack of foundation for
doing so in the specification, and that reviews of the code would have
found the inconsistency between the code and specification, causing the
designers to ask the specification writers why they thought the Ariane V
profile was the same as the Ariane IV. Thus, even without the testing,
the Eiffel system would have uncovered the fault. My argument is that
no designer of a non-trivial safety-critical software system could be
expected to either (a) have such an all-encompassing knowledge of the
total platform to either write or analyze such a complex and subtle
assertion or (b) be willing to add assertions willy-nilly with no basis
in the specification (extranous code being identified as a potential
safety issue in more than one certification scheme).

(As an amusing aside, the defenders of the Eiffel faith were reduced to
calling my objections "casuistry," or using an inappropriate specific
case to prove a general statement. This argument, of course, is using
a specific case to prove a _specific case_. One could argue that the
Eiffel paper produced by Meyer et. al. was a better definition of
casuistry, however!)

> 
> :Or in your own words:
> :
> :> No use of assertions will stop you misinterpreting requirements.
> 
> True, though irrelevant to the point I wasn't making. :)

Not at all irrelevant, unless you claim that assertion writing
is not coupled to requirements (which is a very dangerous claim!).
If you look at failures in safety-critical aerospace software systems
(and I've done more than one study on this),  they tend to be
requirements-driven (e.g. F-18, YF-22, Gripen, Ariane V). More than
one controlled N-version academic study has shown this as well. (One
of the best was where multiple teams implemented a set of flight
control laws, using a basic safety-critical software development
process along the lines of DO-178. There was only one common
fault among all of them - a period in the requirements had been
misinterpreted as a comma due to the poor quality of the paper
version of the control laws!)

You could argue that assertions make the process of eliminating
design faults easier, thus allowing your finite test time to
focus on requirements issues earlier. However, I've talked to
people who build safety-critical aerospace systems (and also read
Safeware,
et. al.) and those kind of issues are usually resolved fairly
quickly in *any* good safety-critical software development process.
There may be some benefit to assertions in this environment, but
it's pretty small when measured against the potential risks.

Again, for a non-safety-critical system, where there may be a
higher proportion of design faults, then you probably do see a
larger benefit (I know I do) for dynamic assertions. For
safety-critical systems that can fail-safe, vs. those that must
fail-operate, I could also see some benefits (although that
class of systems seems to be shirnking every day). However,
beware casuistry! :)

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-13  0:00         ` Jon S Anthony
  1997-07-14  0:00           ` Wes Groleau
  1997-07-15  0:00           ` Don Harrison
@ 1997-07-16  0:00           ` Paul Johnson
  1997-07-16  0:00             ` Ken Garlington
  1997-07-17  0:00             ` Jon S Anthony
  2 siblings, 2 replies; 255+ messages in thread
From: Paul Johnson @ 1997-07-16  0:00 UTC (permalink / raw)



In article <JSA.97Jul13164937@alexandria.organon.com>, 
jsa@alexandria.organon.com says...

>    type Require is boolean range True..True;
>...
>
>    Assert : Require := Complex_Precondition(X);

Interesting idea.  However it does not match Eiffel assertions.

1: Eiffel assertions are only executed at certain times, not at every
invocation of a routine (see E:TL or OOSC2 for the gory details).

2: You can't inherit assertions.  Any such system would require lots
of duplicated assertions.

3: Invariants are still very tricky to support.  You need to call the
invariant checks at the same time as the pre and post conditions.  See
above for details of when this occurs.

4: You had better be pretty sure that the compiler is not going to
optimise your checks into oblivion during debugging, and conversely
you need a way to turn them off for production code.

5: Whilst you could extract the short and flat forms for an Ada class
(sorry, "tagged type"), you can only do so by extending the language
beyond the standard (new special types "require", "ensure", "invariant")
and introducing special coding standards.  This kind of non-standard
language extension is one of the things Ada was designed to avoid.

Paul.

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00       ` Don Harrison
  1997-07-15  0:00         ` Wes Groleau
  1997-07-15  0:00         ` Ken Garlington
@ 1997-07-16  0:00         ` Warwick Pulley
  1997-07-16  0:00           ` Nick Leaton
  1997-07-17  0:00           ` Don Harrison
  2 siblings, 2 replies; 255+ messages in thread
From: Warwick Pulley @ 1997-07-16  0:00 UTC (permalink / raw)



Don Harrison wrote:
> Ken Garlington wrote:
> 
> :But I can do this in Ada, as well, so I don't see the benefit.
> 
> I'm not saying there is any extra benefit - merely that you don't have to 
> wear the overhead of dynamic binding if you're desperate to maximise efficiency.
> Tucker mentioned that overhead. I'm saying it isn't an issue.
> 
> BTW, how do call a procedure under different names in Ada?

By declaring a procedure that "renames" the old one, eg.

procedure ADD_ONE(X: in out INTEGER);
procedure INCREMENT(X: in out INTEGER) renames ADD_ONE;

<large section snipped>

> :There is a school of thought that says to add in assertions, test the
> :system, and
> :then remove/suppress the exceptions. I have seen too many cases of code
> :that works
> :with the assertions active, and then breaks (due to timing differences,
> 
> Yes, timing *is* something to be concerned about when applied to realtime 
> systems. That's why I suggested not using assertions in the hard realtime
> threads of a process. BTW, software designed using DBC may actually run *faster*
> than code without it because you get to strip out all the defensive validity
> checks. You have already ascertained during development that operations are
> called in valid contexts so you don't have to check the context.

In Eiffel that may be true provided that removal of assertion checks doesn't
significantly affect the performance of the code in any way.  The issue of timing,
mentioned by Ken above, is a good example).

I imagine that one needs to take special care when using assertions in
languages that don't fully support them.  From my (sorely lacking!!) knowledge
of Eiffel, clauses that define the precondition and postcondition of an
operation contain exactly one boolean statement which automatically restricts
the coder from including procedural code within these sections.

While this argument favours Eiffel in terms of assertions, it doesn't
mean that porting this functionality to Ada will not introduce other faults.
With Don's demonstration of assertions last Friday (Jul 11 18:05:13 EST) the
postcondition was implemented in the form:

if <assertions on> and then <bool_postcondition>
  raise <postcondition exception>
end if;

The implementation of the assertion is done with multiple statements, so
there is the possibility of important sections of code being inadvertently
added within the "if" statement which would then be removed when assertions
are disabled.

I have seen this happen at least once, where an executable was released to
the test group which AFAIK was only tested with assertions enabled, and then
it was discovered that a crucial line of code was removed because it was
within an assertion block and once this error was encountered the executable
didn't crash but its functionality was imparired severely enough so that
it had to be run again.

Even one error, however minor, is enough to warrant another round of
testing after assertions are removed: at least for languages that don't
fully support assertions.  Even if no errors are discovered in the process
I would consider it a worthwhile exercise, if only to convince myself that
the software functions how I intended.

A suggestion: to avoid some of these problems one could have written two
procedures, say 'precondition' and 'postcondition', each having an 'in'
boolean parameter.  Each procedure should do nothing if assertions are
disabled, but if they are enabled then they would raise the appropriate
exception if the 'in' parameter was false.

Then rather than the above block, one could evaluate a postcondition
by the call:

postcondition(<bool_postcondition>);

and similiarly for preconditions.  A sample implementation of 'postcondition'
(in pseudo-Ada) is:

--------------------------------------------------------------------------------

procedure postcondition(requirement: in boolean) is
begin

# if <assertions on> then

  -- check condition and raise exception if violated
  if not requirement then
    raise <postcondition exception;>
  end if;

# else

  null;

# end if;

end postcondition;
pragma INLINE(postcondition);
--------------------------------------------------------------------------------

So when exceptions are disabled (via a compiler directive), 'postcondition'
would have a null body, and since it's inline there would be no unwanted
procedure call.  It also means that you can conditionally compile
assertions without having to surround each assertion with conditional
compilation directives.

Naturally, my suggestion above still fails to prevent the addition of code
before a precondition check, or after a postcondition check, etc.

> :or more
> :likely code generation errors) to have much confidence in this approach.
> 
> If that's a problem, you need to get your vendor to clean their act up.

Yes, if you know the compiler has a bug in the first place.  The trouble is
that you don't know it's a problem until it occurs, and a compiler could
have a subtle bug that only occurs in very particular circumstances.

Although any respectable compiler has minimal bugs if any, if we don't test
our products after assertions are suppressed then we unnecessarily transform
our confidence in, into dependence on, the vendor's compiler to function
correctly.

It would be irresponsible to deliver software that has only been tested with
assertions enabled, knowing that if an error occurs in the released version
then it's "not my fault".  So for this reason, and for peace of mind, I would
certainly test the version of the software to be delivered to the customer.
Since we expect not to find more errors, this last phase would run smoothly
and quickly.

> :Another consequence of using assertions is that you have to develop and
> :test the
> :assertions. 
> 
> Correct. My initial reaction when I started using them was "Gee, I've got to
> do this extra work on top of writing the "real" code! However, I found I was 
> spending about a third of the time integrating compared with my colleagues
> which meant I was saving time overall and producing more reliable code to boot.

Why should a short integration period automatically imply code reliability?

> :As a result, you need confidence that the benefits of the assertions
> :outweigh the dilution of your test effort.
> 
> IME, they do.

I agree that some type of error checking is in order during development.  I
suppose that whether the results of a failed check is done in the form of a
text message, raising an exception or by other means is a matter for another
thread.

BTW, how do you verify the correctness of your assertions, and that there are
no errors that the assertions didn't find?  Do you prefer code inspection,
or if you do your verification by executing the program itself, how do you
ensure that each section of code is exercised?  Either way, a documentation
of your method would provide a good test which can then be reproduced should
the software be modified.

Happy coding,

Warwick.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-11  0:00   ` Don Harrison
  1997-07-11  0:00     ` James Graves
  1997-07-12  0:00     ` Ken Garlington
@ 1997-07-16  0:00     ` Alan Brain
  1997-07-18  0:00       ` Don Harrison
  2 siblings, 1 reply; 255+ messages in thread
From: Alan Brain @ 1997-07-16  0:00 UTC (permalink / raw)




Don Harrison wrote:
>
> As an example, in our simulation, we have a vehicles object. This is implemented
> as an array of records (they should be variant records discriminated
> on validity, however..). Vehicles are activated and deactivated during the
> course of a "game" by setting a validity flag. I added preconditions to ensure
> that other attributes (such as heading) were not queried unless the vehicle was
> active. These simple checks caught a whole bunch of errors that may otherwise
> have gone unnoticed. In the absence of such a check, the problem may only
> have come to our attention if spurious behaviour was observed. 

Your experience parallels my own, even to the problem domain (I used to
work for STN Atlas Elektronik GmbH of Bremen, Germany makers of fine
machines-that-go-ping)

The difference is that we _did_ use descriminant records. Something
along the lines of:

type TRACK_RECORD_TYPE ( IS_VALID : boolean ) is
record
  case IS_VALID is
    when false => null;
    when true  =>
      -- a whole heap of information
      -- such as relative bearing, time last updated, etc etc
      -- references to threat library, access types to FRAZ and DEMON
grams
      -- and so on.
  end case;
end record;

-- assume you have a declared index type TRACK_INDEX_TYPE, typically a
-- subtype of integer rather than anonymous, and with a range of about
1..1024

type TRACK_STORE_TYPE is array ( TRACK_INDEX_TYPE ) of
TRACK_RECORD_TYPE;

-- Then just declare however many track stores you need of this type...

In use, of course, this meant that unless you made sure that the track
was valid, an exception would be raised. Forex:

 if TRACK_STORE(THIS_TRACK).IS_VALID then
  -- do whatever is needed, the track is valid, so all the fields exist
 end if;

If you missed out this test, then at run time, you'd get an exception
raised,
caused by the fact that if the track ain't valid, then such items as
relative
bearing etc are undefined, irrelevant, and just plain don't exist. Using
this
method, it's just not possible to assign a speed or whatever to an
invalid track.

I realise you know all this (at least in theory) but this is to confirm
that it works in practice too. Many errors were caught this way.

Any reason why descriminant records weren't used in you project? 

-- 
aebrain@dynamite.com.au     <> <>    How doth the little Crocodile
| Alan & Carmel Brain|      xxxxx       Improve his shining tail?
| Canberra Australia |  xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM
100026.2014 compuserve o OO*O^^^^O*OO o oo     oo oo     oo  
                    By pulling MAERKLIN Wagons, in 1/220 Scale
See http://www.z-world.com/graphics/z/master/8856.gif for picture






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00         ` Warwick Pulley
@ 1997-07-16  0:00           ` Nick Leaton
  1997-07-16  0:00             ` Robert Dewar
  1997-07-17  0:00             ` Warwick Pulley
  1997-07-17  0:00           ` Don Harrison
  1 sibling, 2 replies; 255+ messages in thread
From: Nick Leaton @ 1997-07-16  0:00 UTC (permalink / raw)



Warwick Pulley wrote:

> I have seen this happen at least once, where an executable was released to
> the test group which AFAIK was only tested with assertions enabled, and then
> it was discovered that a crucial line of code was removed because it was
> within an assertion block and once this error was encountered the executable
> didn't crash but its functionality was imparired severely enough so that
> it had to be run again.

Can you explain this a bit more. In Eiffel an assertion has to be 
a boolean expression, and I presume that you are not writing a 
boolean expression that has a side effect?

-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00             ` Ken Garlington
@ 1997-07-16  0:00               ` Robert Dewar
  1997-07-17  0:00                 ` Paul Johnson
                                   ` (2 more replies)
  0 siblings, 3 replies; 255+ messages in thread
From: Robert Dewar @ 1997-07-16  0:00 UTC (permalink / raw)



Ken says

<<Meyer et. al. argues that, if the system was written in Eiffel, that
the assertion would have been added despite the lack of foundation for
doing so in the specification, and that reviews of the code would have
found the inconsistency between the code and specification, causing the
designers to ask the specification writers why they thought the Ariane V
profile was the same as the Ariane IV. Thus, even without the testing,
the Eiffel system would have uncovered the fault. My argument is that
>>


In fact the assertion *was* present in the Ada code, in the form of
a language specified check. The claim that somehow the programmer would
have noticed the assertion in Eiffel, while missing it in Ada, is entirely
bogus in my view. This is just a case of waffly language advocacy without
any substance at all.

By the way, does Eiffel have fixed-point types? If not, presumably the
entire code would have been obscured by manual scaling ... And if you
think you can add fixed-point types by simply defining packages, think
again (and take a look at the exp_fixd unit in GNAT to get an idea of
what you are talking about :-)





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00         ` Ken Garlington
@ 1997-07-16  0:00           ` Jean-Marc Jezequel
  1997-07-16  0:00             ` Ken Garlington
  1997-07-17  0:00           ` Joachim Durchholz
  1997-07-18  0:00           ` Don Harrison
  2 siblings, 1 reply; 255+ messages in thread
From: Jean-Marc Jezequel @ 1997-07-16  0:00 UTC (permalink / raw)



In article <33CC0548.4099@flash.net>, Ken Garlington <keg0@flash.net> writes:
>Don Harrison wrote:

>> You would use them anywhere that a piece of code makes assumptions. For example,
>> to help avoid the Ariane fiasco, include contracts in the INS(?) that specify
>> Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
>> you apply Ariane 5 dynamics to it.
>
>This is why my blood pressure goes up!
>
>The _Ada_ implementation did generate an assertion violation the very
>first time Ariane 5 dynamics were applied to it. Unfortunately, the very first time
>Ariane 5 dynamics were applied to it was at LANUCH!

>They were not applied earlier, because the contractor assumed that the
>Ariane 5 dynamics were the same as the Ariane 4, so why spend the money testing
>to the same conditions already tested earlier? (They were wrong, of course, but they
>didn't know that at the time).

At the risk of repeating myself, and reopening a thread beaten to death,
the all point of design by contract (DBC) is to
make this kind of assumptions explicit. Ariane 5 is just a nice striking example
of working with assumptions that are true at a point in time (Ariane 4) and no longer
later on (Ariane 5). I think we agreed on this previously.

To sum up your point, you think that DBC, i.e. expressing hidden assumptions with 
Eiffel-like assertions would not have been practicable in this case.
Others think it would have...

You seem to be a specialist in flight software. We are not. But specialists might,
from time to time, learn something from people with a broader perspective
(this is a general statement, I do not claim in particular that I have a broader
perspective than you, or anyone else for that matter;-).

Basically, our arguments failed to convinced you. Yours failed to convince us. 
That's life, and I hope readers can make their mind themselves instead of
relying on the one of us who shouts louder.

>The other part of the problem was that the _response_ to the assertion
>violation was wrong. The designer assumed the assertion would occur due to a hardware
>failure, not a software requirements failure, and so the handler shut down the
>"offending" hardware, rather than attempting some other action (e.g. replacing the
>out-of-range value with a "safe" value). Frankly, I don't know that I would have written the
>handler differently myself.

Agreed, that's a different problem altogether.

>According to Meyer, et. al. Eiffel programmers would have written the
>handler differently, and also they would have known to do the testing
>differently (even though the requirements specification said that the tests need not change).
>However, their explanation as to why this is true is far from convincing (basically,
>that "Eiffel programmers believe in quality" or some such nonsense). Their "analysis"
>is also on the Web. I've asked them to post my rebuttal to their paper, but I
>don't know if they ever did.

Just for the record, I'm still waiting for your rebuttal paper to put it on my web alongside
with the Computer article. 

PS: Ken's post was brought to my attention by a colleague: I don't have time to check the news
very often these days, and anyway I won't follow-up on this thread to avoid reopening the interminable
Ariane thread.

-- 
Jean-Marc Jezequel               Tel : +33 299 847 192         
IRISA/CNRS                       Fax : +33 299 847 171         
Campus de Beaulieu               e-mail : jezequel@irisa.fr 
F-35042 RENNES (FRANCE)          http://www.irisa.fr/pampa/PROF/jmj.html




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00           ` Paul Johnson
@ 1997-07-16  0:00             ` Ken Garlington
  1997-07-17  0:00               ` Paul Johnson
  1997-07-17  0:00             ` Jon S Anthony
  1 sibling, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-16  0:00 UTC (permalink / raw)



Paul Johnson wrote:
> 
> In article <JSA.97Jul13164937@alexandria.organon.com>,
> jsa@alexandria.organon.com says...
> 
> >    type Require is boolean range True..True;
> >...
> >
> >    Assert : Require := Complex_Precondition(X);
> 
> Interesting idea.  However it does not match Eiffel assertions.
> 
> 1: Eiffel assertions are only executed at certain times, not at every
> invocation of a routine (see E:TL or OOSC2 for the gory details).

OK, so Eiffel's different. What's the significant advantage of this
approach.

> 
> 2: You can't inherit assertions.  Any such system would require lots
> of duplicated assertions.

Why would I have to duplicate assertions?

> 
> 3: Invariants are still very tricky to support.  You need to call the
> invariant checks at the same time as the pre and post conditions.  See
> above for details of when this occurs.

Again, I'm not trying to duplicate Eiffel. How much do I lose if Ada
invariants
are different?

> 
> 4: You had better be pretty sure that the compiler is not going to
> optimise your checks into oblivion during debugging, and conversely
> you need a way to turn them off for production code.

Actually, I don't mind the checks being "optimized into oblivion" if the
compiler can deduce that they are unnecessary, and I certainly don't
want
to exercise one kind of code during development and another during test.
The alternative (as was proposed by one Eiffel advocate) is to not use
_any_ assertions for hard real-time threads.

If Eiffel compilers do no optimizations of assertions, and there are a
lot of complex assertions in Eiffel code, what does this say for the
efficiency of the code?

> 5: Whilst you could extract the short and flat forms for an Ada class
> (sorry, "tagged type"), you can only do so by extending the language
> beyond the standard (new special types "require", "ensure", "invariant")
> and introducing special coding standards.  This kind of non-standard
> language extension is one of the things Ada was designed to avoid.

Why would you want to _extract_ such information? The contract is in the
Ada specification in all of my code, at the level of detail I want
public.

> 
> Paul.
> 
> --
> Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
> +44 1245 242244         +-----------+-----------------------------------------+
> Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
> Home: <Paul@treetop.demon.co.uk>    | standards, all different.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00           ` Jean-Marc Jezequel
@ 1997-07-16  0:00             ` Ken Garlington
  1997-07-17  0:00               ` "Paul E. Bennett"
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-16  0:00 UTC (permalink / raw)



Jean-Marc Jezequel wrote:
> 
> In article <33CC0548.4099@flash.net>, Ken Garlington <keg0@flash.net> writes:
> >Don Harrison wrote:
> 
> >> You would use them anywhere that a piece of code makes assumptions. For example,
> >> to help avoid the Ariane fiasco, include contracts in the INS(?) that specify
> >> Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
> >> you apply Ariane 5 dynamics to it.
> >
> >This is why my blood pressure goes up!
> >
> >The _Ada_ implementation did generate an assertion violation the very
> >first time Ariane 5 dynamics were applied to it. Unfortunately, the very first time
> >Ariane 5 dynamics were applied to it was at LANUCH!
> 
> >They were not applied earlier, because the contractor assumed that the
> >Ariane 5 dynamics were the same as the Ariane 4, so why spend the money testing
> >to the same conditions already tested earlier? (They were wrong, of course, but they
> >didn't know that at the time).
> 
> At the risk of repeating myself, and reopening a thread beaten to death,
> the all point of design by contract (DBC) is to
> make this kind of assumptions explicit.

Which would not have happened in the Ariane V case.

> Ariane 5 is just a nice striking example
> of working with assumptions that are true at a point in time (Ariane 4) and no longer
> later on (Ariane 5). I think we agreed on this previously.

Yes. However, the assumption would not have been documented via an
Eiffel assertion,
as I claimed and you/Meyer never refuted (except to exclaim,
"casuistry!").

> 
> To sum up your point, you think that DBC, i.e. expressing hidden assumptions with
> Eiffel-like assertions would not have been practicable in this case.
> Others think it would have...

The distinction, of course, is that I gavce specific reasons why it
would not
have happened. Please post the evidence stating that the assertion would
have been
added (beyond the bizarre "Eiffel programmers are more careful"
argument).


> You seem to be a specialist in flight software. We are not. But specialists might,
> from time to time, learn something from people with a broader perspective
> (this is a general statement, I do not claim in particular that I have a broader
> perspective than you, or anyone else for that matter;-).

Unfortunately, the reverse is never true. Generalists never listen to or
learn from
specialists.

Consider the work of "generalists" that is incorporated into my code
today: Ada (Ichbiah
et. al.), object-based design principles (Gomaa/SPC, which in turn is
based on a lot
of previous work), safety-critical design (Levison and many others),
testing practices
(Beizer, et. al.)... there are many examples.

In your work on Ariane V, what specialists in the flight software field
(from
Arianespace or elsewhere) did you use to review your paper prior to its
publication?

After its publication, how many specialists in this field publicly (or
privately)
supported your position? I certainly was not the only one to object
publicly!

> Basically, our arguments failed to convinced you. 

Unfortunately, you failed to even discuss some of the points I (and
others) made.

> Yours failed to convince us.
> That's life, and I hope readers can make their mind themselves instead of
> relying on the one of us who shouts louder.

Yes, perhaps other criteria would be better. What would you suggest?
Company
revenues?

I would have thought practical experience would be a strong
determinant...

> >The other part of the problem was that the _response_ to the assertion
> >violation was wrong. The designer assumed the assertion would occur due to a hardware
> >failure, not a software requirements failure, and so the handler shut down the
> >"offending" hardware, rather than attempting some other action (e.g. replacing the
> >out-of-range value with a "safe" value). Frankly, I don't know that I would have written the
> >handler differently myself.
> 
> Agreed, that's a different problem altogether.

But an important one, if the assertion is left in the code. If the
assertion is removed
from the code, then other risks emerge.

> 
> >According to Meyer, et. al. Eiffel programmers would have written the
> >handler differently, and also they would have known to do the testing
> >differently (even though the requirements specification said that the tests need not change).
> >However, their explanation as to why this is true is far from convincing (basically,
> >that "Eiffel programmers believe in quality" or some such nonsense). Their "analysis"
> >is also on the Web. I've asked them to post my rebuttal to their paper, but I
> >don't know if they ever did.
> 
> Just for the record, I'm still waiting for your rebuttal paper to put it on my web alongside
> with the Computer article.

I thought I sent you the summary from the previous thread. I apologize.
I will go into
DejaNews and re-send it this weekend.

> 
> PS: Ken's post was brought to my attention by a colleague: I don't have time to check the news
> very often these days, and anyway I won't follow-up on this thread to avoid reopening the interminable
> Ariane thread.

Unfortunately, it's already been re-opened. As I feared, people are
using your paper to
"prove" the worth of DBC/Eiffel in safety-critical systems, although no
one has yet
published a list of such systems that have been written in Eiffel.

> 
> --
> Jean-Marc Jezequel               Tel : +33 299 847 192
> IRISA/CNRS                       Fax : +33 299 847 171
> Campus de Beaulieu               e-mail : jezequel@irisa.fr
> F-35042 RENNES (FRANCE)          http://www.irisa.fr/pampa/PROF/jmj.html




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00           ` Nick Leaton
@ 1997-07-16  0:00             ` Robert Dewar
  1997-07-20  0:00               ` Joachim Durchholz
  1997-07-21  0:00               ` Don Harrison
  1997-07-17  0:00             ` Warwick Pulley
  1 sibling, 2 replies; 255+ messages in thread
From: Robert Dewar @ 1997-07-16  0:00 UTC (permalink / raw)



<<Can you explain this a bit more. In Eiffel an assertion has to be
a boolean expression, and I presume that you are not writing a
boolean expression that has a side effect?
>>


The evaluation of any boolean expressoin has side effects at the level
we are talking about, at the very least it takes time and can affect
timing relationships, which of course in this kind of code can be
critical.

The idea that REMOVING the evaluation of boolean expressions completely
is semantically neutral is also completely bogus. Such removal can affect
Icache locality of the code that is left, again affecting timing, and can
also result in code being at different locations, resulting in differences
of behavior with unbounded consequences.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00               ` Paul Johnson
@ 1997-07-17  0:00                 ` Ken Garlington
  1997-07-18  0:00                   ` Paul Johnson
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-17  0:00 UTC (permalink / raw)



Paul Johnson wrote:
> 
> In article <33CD6207.6007@flash.net>, kennieg@flash.net says...
> >
> >Paul Johnson wrote:
> 
> >> 1: Eiffel assertions are only executed at certain times, not at every
> >> invocation of a routine (see E:TL or OOSC2 for the gory details).
> >
> >OK, so Eiffel's different. What's the significant advantage of this
> >approach.
> 
> However if you call a routine from within a class, there is nothing to
> say that the assertions have to be maintained.  In fact it would be
> very restrictive to say that they must be.

OTOH, wouldn't I want the option to see if intra-class dependencies
cause
assertions to be violated? (Actually, in my case, I generally do want
this...)

Certainly, if I wanted to have my Ada exceptions raised only from an
external caller, it would not be particularly difficult to structure my
package to do this. So, other than maybe writing a little less code,
what's
the significant advantage of this approach? Is it safer to not enforce
assertions for intra-class dependencies?

I still don't see the big advantage from a safety-critical
perspective...

> >> 2: You can't inherit assertions.  Any such system would require lots
> >> of duplicated assertions.
> >
> >Why would I have to duplicate assertions?
> 
> Because of the Liskov Substitutability Principle.

To expand: Why do I have to duplicate assertions _in Ada_?

> >> 3: Invariants are still very tricky to support.  You need to call the
> >> invariant checks at the same time as the pre and post conditions.  See
> >> above for details of when this occurs.
> 
> >Again, I'm not trying to duplicate Eiffel. How much do I lose if Ada
> >invariants are different?
> 
> See above.

Ditto.

> >> 4: You had better be pretty sure that the compiler is not going to
> >> optimise your checks into oblivion during debugging, and conversely
> >> you need a way to turn them off for production code.
> >
> >Actually, I don't mind the checks being "optimized into oblivion" if the
> >compiler can deduce that they are unnecessary,
> 
> In many compilers, if you say "assert: require = (a > b)" then the compiler
> will observe that the value of "require" is not used thereafter, and
> remove the statement.

Since this isn't Ada, I couldn't comment.

> 
> >and I certainly don't
> >want
> >to exercise one kind of code during development and another during test.
> 
> The whole point of Eiffel assertions is that in a correct program they
> have no effect on execution.  Therefore you get exactly the same results
> whether they are enabled or not.

This would require (a) no changes in timing and (b) zero probability
that
the compiler generates incorrect code with a certain combination of
compiler switches and code. I am skeptical.

> Apart from assertion exceptions, the only way that the execution of an
> assertion can make a difference is if you call a function with side effects.
> Eiffel functions are specifically banned from having side effects.

See above.

> Of course, you *can* leave them enabled, but it slows down your code.

It does something else. It requires you to decide what to do if the
assertion is violated during execution.

> >If Eiffel compilers do no optimizations of assertions, and there are a
> >lot of complex assertions in Eiffel code, what does this say for the
> >efficiency of the code?
> 
> The point of assertions is to detect errors during debugging.  Some people
> leave preconditions on in production code as well, if there are no speed
> problems as a result.

What do they do if the assertion is violated?

> 
> >> [Difficulty of getting "short-flat" forms]
> 
> >Why would you want to _extract_ such information? The contract is in the
> >Ada specification in all of my code, at the level of detail I want
> >public.
> 
> No its not. 

You haven't read my Ada specs!

> The point of software contracting is that the public assertions
> are just that: public.  They are shown in the class interface (the short-flat
> form). 

Exactly. The Ada specification is just that: the public part. In fact,
it's
included in our software user's manual for OS-type software for that
reason.
It defines what the user needs to know, and nothing else. (Actually, we
do have to do one thing: we suppress printing of the private part, much
like
Eiffel uses documentation tools to extract the class specification.)

> Eiffel takes a different attitude to Ada here, and I can see the case
> for the Ada approach.  Instead of writing interface and implementation in
> separate files, Eiffel provides tools to extract the interface information
> from the implementation.  The public assertions are part of the interface,
> because they specify the class behaviour to its clients.
> 
> The Ada approach has the advantage that you can easily lock the interface
> while allowing changes to the implementation.  In Eiffel this could be
> achieved by recording the short-flat form of a class (the interface) and
> checking that the new short-flat form still matches after any change is made.
> Its just a bit more hassle to organise.

Right, although I don't the organization as a signficant issue. I would
be
more worried about making an inadvertant change, and failing to do the
check
afterwards.

Of course, I suspect you could acheive the same effect in Eiffel by
having the code
in multiple files, and using a CM system to merge the files as needed.

> 
> Part of the important thing about the short-flat form is that it includes
> *all* the interface information about a class, including any features inherited
> from ancestors.  This is important, particularly in the presence of multiple
> inheritance.  It means that programmers don't have to search through listings
> to reconstruct it manually.

> If you wanted to design a dialect of Ada with software contracting built
> in properly then you would have to bring the public assertions into the
> interface file.  And you would still need the equivalent of "flat" to bring
> all the ancestor features into your class.

You can do this in Ada, too, with the proper documentation tools. It's
just
a bit more of a hassle to organize :)

> 
> Paul.
> 
> --
> Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
> +44 1245 242244         +-----------+-----------------------------------------+
> Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
> Home: <Paul@treetop.demon.co.uk>    | standards, all different.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00           ` Paul Johnson
  1997-07-16  0:00             ` Ken Garlington
@ 1997-07-17  0:00             ` Jon S Anthony
       [not found]               ` <EDHqKo.K52@world.std.com>
  1 sibling, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-07-17  0:00 UTC (permalink / raw)



In article <5qi26c$8ll$2@miranda.gmrc.gecm.com> paul.johnson@gecm.com (Paul Johnson) writes:

> In article <JSA.97Jul13164937@alexandria.organon.com>, 
> jsa@alexandria.organon.com says...
> 
> >    type Require is boolean range True..True;
> >...
> >
> >    Assert : Require := Complex_Precondition(X);
> 
> Interesting idea.  However it does not match Eiffel assertions.

Never said it did.  I simply said that the complexity of the condition
does not prevent a similar expression in Ada to that in Eiffel.  That
still stands.


> 1: Eiffel assertions are only executed at certain times, not at every
> invocation of a routine (see E:TL or OOSC2 for the gory details).

Yeah, I've looked at this - what's the point??


> 2: You can't inherit assertions.  Any such system would require lots
> of duplicated assertions.

Sigh, for the _umpteenth_ time: Yes you can!  The correct statement
here is that you don't have _general_ class invariants without
"programming" them.  But constraints _are_ inherited.  And besides,
why is just waving "inheritance" around supposed to mean something
"important"??!?!?  Believe me - from my perspective it has _long_
since lost any magical luster it may have once had in SWE.


> 3: Invariants are still very tricky to support.  You need to call the
> invariant checks at the same time as the pre and post conditions.  See
> above for details of when this occurs.

This is just point 2 repeated...


> 4: You had better be pretty sure that the compiler is not going to
> optimise your checks into oblivion during debugging, and conversely
> you need a way to turn them off for production code.

???  As long as it is _legal_ (does not change the _meaning_ of the
code) this would be a _good_ thing!  It amounts to verification at
_compile_ time.


> 5: Whilst you could extract the short and flat forms for an Ada class
> (sorry, "tagged type"), you can only do so by extending the language
> beyond the standard (new special types "require", "ensure", "invariant")
> and introducing special coding standards.  This kind of non-standard
> language extension is one of the things Ada was designed to avoid.

Who cares about the bogus short flat form?  That is simply an error
prone method for describing interfaces.  Ada has no need for it as it
makes this stuff explicit!

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00         ` Ken Garlington
  1997-07-16  0:00           ` Jean-Marc Jezequel
@ 1997-07-17  0:00           ` Joachim Durchholz
  1997-07-19  0:00             ` Ken Garlington
  1997-07-21  0:00             ` Robert S. White
  1997-07-18  0:00           ` Don Harrison
  2 siblings, 2 replies; 255+ messages in thread
From: Joachim Durchholz @ 1997-07-17  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> > You would use them anywhere that a piece of code makes assumptions.
> For example,
> > to help avoid the Ariane fiasco, include contracts in the INS(?)
> that specify
> > Ariane 4 dynamics. Then, in testing, you will get an assertion
> violation when
> > you apply Ariane 5 dynamics to it.
> 
> This is why my blood pressure goes up!
> 
> The _Ada_ implementation did generate an assertion violation the very
> first time
> Ariane 5 dynamics were applied to it. Unfortunately, the very first
> time
> Ariane 5
> dynamics were applied to it was at LANUCH!
> 
> They were not applied earlier, because the contractor assumed that the
> Ariane 5
> dynamics were the same as the Ariane 4, so why spend the money testing
> to the same
> conditions already tested earlier? (They were wrong, of course, but
> they
> didn't know
> that at the time).

<Sigh> that misunderstanding again. The issue in the Ariane-5 paper by
Meyer and Jezequel isn't that the preconditions per se would have
changed anything. The issue is that the preconditions would have been an
integral part of the routine's signature, and thus not likely to have
been overlooked by the team that ported the Ariane-4 code to Ariane-5.
As it were, the preconditions were buried in some obscure part of the
documentation, and management didn't reread everything when they reused
the code (together with its hardware).

The paper may not be very clear in this respect (I got Meyer's view on
the topic from his book, not from the paper), or people might
misinterpret what it's saying.

> According to Meyer, et. al. Eiffel programmers would have written the
> handler
> differently, and also they would have known to do the testing
> differently (even though
> the requirements specification said that the tests need not change).

No. They would have written the handler the same way, and documented the
precondition with the routine where it belongs, not in some obscure spec
sheets that are shelved away.

> However, their
> explanation as to why this is true is far from convincing (basically,
> that "Eiffel
> programmers believe in quality" or some such nonsense).

Well, believing in quality is far from nonsense. And assertions do
certainly promote a certain style of quality-mindedness.
It is similar to declaring types for routine parameters. Early C didn't
have them, current C compilers have them. And besides catching lousy
errors, the need to declare parameter types makes the programmers
*think* about what's the right type for a parameter, instead of just
writing it down. A similar mechanism is at work with assertions and
Eiffel programmers.

> They believe that "software is software." and apply the
> expertise in their
> domain to mine.

Well, their finding may have been badly presented, but I think the
"software is software" approach is valid. Of course there are
differences between various levels of safety requirements, but some
basic themes apply all the same - like static typing, or the need to
choose meaningful names, etc. Meyer believes that assertions should be
considered one of these basic themes, and that assertions might have
prevented the Ariane-5 crash, for the reasons given above. (And I'm very
much with him, though I'm not informed enough about the Ariane-5 crash
to decide wether it is a particularly good example of the issue.)

> I am aware of at least one project developing an embedded missile
> controller,
> that did exactly what you describe (in Ada). Here's what happened:
> 
> 1. Their timings changed, which introduced some subtle differences in
> the
> relationships between tasks and external interrupts. Some of these
> subtle
> differences invalidated their original testing.

Timing on that basis is the one thing that Eiffel isn't built for.
Adding a new class might not change subtle timings, it might totally
alter the microscopic behaviour of the program. For example,
non-polymorphic routine calls that could be statically bound by the
compiler might become polymorphic and required a dynamic dispatch.
Fine-tuning code so that certain routines are guaranteed to take at
least x ms and at most y ms sounds to me like a very difficult and
fragile thing to achieve in Eiffel.

> 3. At least one compiler bug was introduced, which was definitely
> unsettling.

That's a problem of compiler quality. Eiffel doesn't guarantee perfect
compilers, but assertions should make bugs less likely.

> The other prong of this is that, while assertions are keen for
> catching
> design problems, I haven't seen much evidence that they catch
> high-level
> requirements problems (not surprising, since the code was presumably
> written
> to match the requirements). In 13 years of developing safety-critical
> embedded systems, our process tends to handle design problems fairly
> early.
> It's those high-level requirements problems where we need the most
> help.

Eiffel is the only language that I know that can scale up to formalizing
high-level requirements. The technique is easy: write a few abstract
("deferred") classes that aren't much more than a set of routine
signatures and assertions.
One can even implement such a system: Just take the design classes as
ancestors for your implementation classes. Descendants must keep the
assertions, so your code is guaranteed to match the specs (in a way -
assertions aren't statically checked).

> But almost all of our safety-critical threads are hard realtime
> threads!
> That's a HUGE limitation for our systems!

Well, if you don't have confidence in the compiler, there isn't much you
can do to remove assertions (or run-time range checking, which are a
limited form of assertions).
But in this domain there's no difference between Eiffel and Ada - the
problem's the same, and there is no satisfactory solution available.

BTW I'm somewhat curious how these subtle timing differences come to
have practical consequences. I'm not a hard real-time engineer, so I'd
expect it doesn't matter if a routine runs faster than expected. How
come that your experience is obviously different?

> What is the process to certify Eiffel compilers as being acceptably
> mature
> (code generation-wise) for safety-critical systems? Is all testing
> performed
> with assertions on and assertions off in all test cases?

There isn't even a testbed available - probably because nobody earnestly
demanded it yet.

> However, what about the topic of this thread (safety-critical
> systems)?
> It sounds
> like there's a lot of limitations as to using (and inheriting)
> assertions for
> this environment.

I think OO in general is difficult to apply here. You obviously need
tight control on the code generated, to control the timings. A good
Eiffel compiler will do a global analysis of the system and apply
inter-routine optimizations. This makes the type of control you desire
difficult, and I'm not sure wether the better reliability is worth the
price.

> > :Of course, Bertand Meyer's Eiffel website insists that even
> > :misinterpretation of
> > :requirements (Ariane V) will be a problem no longer when Eiffel is
> used!
> >
> > Come on. He's not saying that.
> 
> Read his analysis of Ariane V. He says _exactly_ that, and has
> defended
> saying that in multiple newsgroups. A smart person, but not someone
> who knows my domain particularly well.

The Ariane-5 crash wasn't a requirements misinterpretation. It was
overlooking a part of the requirements.

Regards,
Joachim
-- 
Please don't send unsolicited ads.






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00           ` Nick Leaton
  1997-07-16  0:00             ` Robert Dewar
@ 1997-07-17  0:00             ` Warwick Pulley
  1997-07-17  0:00               ` Warwick Pulley
  1997-07-17  0:00               ` Nick Leaton
  1 sibling, 2 replies; 255+ messages in thread
From: Warwick Pulley @ 1997-07-17  0:00 UTC (permalink / raw)



In article <33CD1722.2D24@calfp.co.uk>, Nick Leaton <nickle@calfp.co.uk> writes:
> Warwick Pulley wrote:
> 
> > I have seen this happen at least once, where an executable was released to
> > the test group which AFAIK was only tested with assertions enabled, and then
> > it was discovered that a crucial line of code was removed because it was
> > within an assertion block and once this error was encountered the executable
> > didn't crash but its functionality was imparired severely enough so that
> > it had to be run again.
> 
> Can you explain this a bit more. In Eiffel an assertion has to be 
> a boolean expression, and I presume that you are not writing a 
> boolean expression that has a side effect?

Personally I haven't used assertions to their full extent although I like
to have error checking in place.  It turned out that the problem lay not in
the boolean expression itself, but how it was used.  The example I was
referring to above, which was also modelled in Ada, was not of the
form:

    -- example 1
    if <assertions on> and then not <check> then
      raise <postcondition error>
    end if;

    return <value>

but looked like:

    -- example 2
    if <assertions on> and then <check> then
      return <value>
    end if;
    raise <postcondition error>;

This of course worked fine when assertions were on because when the check was
satisfied a value was returned and the assertion was avoided.  When assertions
were switched off and the procedure got called, an exception was raised
unconditionally and broke the software during testing.

I my last post I mentioned a method of using assertions in Ada to address this
problem, namely by using *one-line* calls to inline precondition and
postcondition checking procedures.  They also had the advantage that the
assertions could be included only when a compiler directive was set to TRUE,
rather than using a boolean statement.  When assertions were off, the body of
the procedure would be a "null;" statement which would get optimised out.  I
hope.  :)

Example 2 above is an example how the assertions can be "mis-implemented" in
Ada, because the logic is wrong and necessary code was included in the "if"
statement.  As you have said, all you need in Eiffel is the boolean
expression itself, and since Eiffel has a special clauses for these
assertions it's not possible to include vital procedural code within these
clauses.

Although I made the point about Ada specifically, I then made it
unnecessary by making the broader statement that I would be uneasy about
releasing software that was untested with assertions removed.  This would
be whether the language I program in supports assertions or not, and I
guess the same goes for any software that's released in a different form
to which it is tested.

> -- 
> 
> Nick

Regards,

Warwick.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00             ` Warwick Pulley
@ 1997-07-17  0:00               ` Warwick Pulley
  1997-07-17  0:00               ` Nick Leaton
  1 sibling, 0 replies; 255+ messages in thread
From: Warwick Pulley @ 1997-07-17  0:00 UTC (permalink / raw)



Apologies to those who have read this twice: I think I failed to set the
distribution properly last time.

Warwick.
--------------------------------



In article <33CD1722.2D24@calfp.co.uk>, Nick Leaton <nickle@calfp.co.uk> writes:
> Warwick Pulley wrote:
> 
> > I have seen this happen at least once, where an executable was released to
> > the test group which AFAIK was only tested with assertions enabled, and then
> > it was discovered that a crucial line of code was removed because it was
> > within an assertion block and once this error was encountered the executable
> > didn't crash but its functionality was imparired severely enough so that
> > it had to be run again.
> 
> Can you explain this a bit more. In Eiffel an assertion has to be 
> a boolean expression, and I presume that you are not writing a 
> boolean expression that has a side effect?

Personally I haven't used assertions to their full extent although I like
to have error checking in place.  It turned out that the problem lay not in
the boolean expression itself, but how it was used.  The example I was
referring to above, which was also modelled in Ada, was not of the
form:

    -- example 1
    if <assertions on> and then not <check> then
      raise <postcondition error>
    end if;

    return <value>

but looked like:

    -- example 2
    if <assertions on> and then <check> then
      return <value>
    end if;
    raise <postcondition error>;

This of course worked fine when assertions were on because when the check was
satisfied a value was returned and the assertion was avoided.  When assertions
were switched off and the procedure got called, an exception was raised
unconditionally and broke the software during testing.

I my last post I mentioned a method of using assertions in Ada to address this
problem, namely by using *one-line* calls to inline precondition and
postcondition checking procedures.  They also had the advantage that the
assertions could be included only when a compiler directive was set to TRUE,
rather than using a boolean statement.  When assertions were off, the body of
the procedure would be a "null;" statement which would get optimised out.  I
hope.  :)

Example 2 above is an example how the assertions can be "mis-implemented" in
Ada, because the logic is wrong and necessary code was included in the "if"
statement.  As you have said, all you need in Eiffel is the boolean
expression itself, and since Eiffel has a special clauses for these
assertions it's not possible to include vital procedural code within these
clauses.

Although I made the point about Ada specifically, I then made it
unnecessary by making the broader statement that I would be uneasy about
releasing software that was untested with assertions removed.  This would
be whether the language I program in supports assertions or not, and I
guess the same goes for any software that's released in a different form
to which it is tested.

> -- 
> 
> Nick

Regards,

Warwick.






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00             ` Ken Garlington
@ 1997-07-17  0:00               ` Paul Johnson
  1997-07-17  0:00                 ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Paul Johnson @ 1997-07-17  0:00 UTC (permalink / raw)



In article <33CD6207.6007@flash.net>, kennieg@flash.net says...
>
>Paul Johnson wrote:

>> 1: Eiffel assertions are only executed at certain times, not at every
>> invocation of a routine (see E:TL or OOSC2 for the gory details).
>
>OK, so Eiffel's different. What's the significant advantage of this
>approach.

The thing to understand about Eiffel assertions is that the mechanism was
not thrown together in an ad-hoc manner.  The "public" assertions (pre and
post conditions, and invariants) are there to support the production of
correct classes.  A class is "correct" in the Eiffel sense if a client
can never see a postcondition or invariant violated, provided that the
client follows the preconditions.

However if you call a routine from within a class, there is nothing to
say that the assertions have to be maintained.  In fact it would be
very restrictive to say that they must be.

What this comes down to is that if I write

   object.foo (arg1, arg2)

then the appropriate assertions should be tested.  OTOH if I write

   foo (arg1, arg2)

then the assertions should *not* be tested.

>> 2: You can't inherit assertions.  Any such system would require lots
>> of duplicated assertions.
>
>Why would I have to duplicate assertions?

Because of the Liskov Substitutability Principle.  A class must be able
to stand in for its ancestors.  Therefore it has to inherit the contracts
of its ancestors.  Therefore when you redefine a routine you need to copy 
the assertions from the ancestor.  Ditto for the invariants.

Eiffel does this automatically.

>> 3: Invariants are still very tricky to support.  You need to call the
>> invariant checks at the same time as the pre and post conditions.  See
>> above for details of when this occurs.

>Again, I'm not trying to duplicate Eiffel. How much do I lose if Ada
>invariants are different?

See above.  Remember also that if a routine is not redefined in a descendant,
it still has to check the descendant's invariants rather than just the
ancestors.  You need to define a routine "invariant_check".  To add new
invariants in a descendant, you redefine this routine to check the new
invariant and then call it's ancestor version(s).

>> 4: You had better be pretty sure that the compiler is not going to
>> optimise your checks into oblivion during debugging, and conversely
>> you need a way to turn them off for production code.
>
>Actually, I don't mind the checks being "optimized into oblivion" if the
>compiler can deduce that they are unnecessary,

In many compilers, if you say "assert: require = (a > b)" then the compiler
will observe that the value of "require" is not used thereafter, and
remove the statement.

>and I certainly don't
>want
>to exercise one kind of code during development and another during test.

The whole point of Eiffel assertions is that in a correct program they
have no effect on execution.  Therefore you get exactly the same results
whether they are enabled or not.

Apart from assertion exceptions, the only way that the execution of an
assertion can make a difference is if you call a function with side effects.
Eiffel functions are specifically banned from having side effects.

Of course, you *can* leave them enabled, but it slows down your code.

>If Eiffel compilers do no optimizations of assertions, and there are a
>lot of complex assertions in Eiffel code, what does this say for the
>efficiency of the code?

The point of assertions is to detect errors during debugging.  Some people
leave preconditions on in production code as well, if there are no speed
problems as a result.

>> [Difficulty of getting "short-flat" forms]

>Why would you want to _extract_ such information? The contract is in the
>Ada specification in all of my code, at the level of detail I want
>public.

No its not.  The point of software contracting is that the public assertions
are just that: public.  They are shown in the class interface (the short-flat
form).  Eiffel takes a different attitude to Ada here, and I can see the case
for the Ada approach.  Instead of writing interface and implementation in 
separate files, Eiffel provides tools to extract the interface information
from the implementation.  The public assertions are part of the interface,
because they specify the class behaviour to its clients.

The Ada approach has the advantage that you can easily lock the interface
while allowing changes to the implementation.  In Eiffel this could be
achieved by recording the short-flat form of a class (the interface) and
checking that the new short-flat form still matches after any change is made.
Its just a bit more hassle to organise.

Part of the important thing about the short-flat form is that it includes
*all* the interface information about a class, including any features inherited
from ancestors.  This is important, particularly in the presence of multiple
inheritance.  It means that programmers don't have to search through listings
to reconstruct it manually.

If you wanted to design a dialect of Ada with software contracting built
in properly then you would have to bring the public assertions into the
interface file.  And you would still need the equivalent of "flat" to bring
all the ancestor features into your class.

Paul.

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00               ` Robert Dewar
@ 1997-07-17  0:00                 ` Paul Johnson
  1997-07-17  0:00                   ` Jon S Anthony
                                     ` (2 more replies)
  1997-07-18  0:00                 ` Don Harrison
  1997-07-20  0:00                 ` Don Harrison
  2 siblings, 3 replies; 255+ messages in thread
From: Paul Johnson @ 1997-07-17  0:00 UTC (permalink / raw)



In article <dewar.869066151@merv>, dewar@merv.cs.nyu.edu says...
>
>Ken says

>In fact the assertion *was* present in the Ada code, in the form of
>a language specified check. The claim that somehow the programmer would
>have noticed the assertion in Eiffel, while missing it in Ada, is entirely
>bogus in my view. This is just a case of waffly language advocacy without
>any substance at all.

Whilst I don't agree with Meyer that Eiffel would probably have prevented
the Ariane crash, he does have a point.

The thing is that in Eiffel the assertions are not just a run-time error
detection mechanism, they are also a documentation and specification
mechanism.  The Ada assertion was invisible because it was buried in the
implementation of the routine that failed.  An equivalent Eiffel routine
(if it were correct) would have had the assertion in its interface, and
so on up to the top level of the software package under discussion.  So
anyone reusing the package would have seen the assertion.  The Inquiry
specifically commented that the Ada assertion was buried so deeply that
it was effectively invisible to any review.

Where this argument falls down, I'm afraid, is that the package did not
receive its data from another software package, but from a hardware
sensor.  At this point the whole idea breaks down.  A pity.

>By the way, does Eiffel have fixed-point types? If not, presumably the
>entire code would have been obscured by manual scaling ...

No, it does not have fixed point types.  And I agree that they cannot
easily be added by library classes.

Paul.

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00         ` Warwick Pulley
  1997-07-16  0:00           ` Nick Leaton
@ 1997-07-17  0:00           ` Don Harrison
  1997-07-17  0:00             ` Karel Th�nissen
                               ` (2 more replies)
  1 sibling, 3 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-17  0:00 UTC (permalink / raw)



Sorry, this response is interminably long...


Warwick Pulley wrote:

:Don Harrison wrote:

:> BTW, how do call a procedure under different names in Ada?
:
:By declaring a procedure that "renames" the old one, eg...

Yes, I should have realised! It's the old workaround to the infuriating Ada83 
visibility problem of not being able to see the predefined operators of a user-defined(?) type in client code. In spite of already with-ing the 
supplier module (which I don't think you should have to do, anyway - if you 
*use* features exported by a package, explicitly importing it is redundant), 
you can't see (hence, use) the imported operators.

While Ada95 has ameliorated this restriction via the "with <type>"(?) statement,
it doesn't go far enough, IMO. Better would be removing the need for any
explicit importation of operators. Even better, IMO, would be removing explicit 
imports of everything (including packages). However, I guess the existence 
of "use" clauses would then create ambiguity problems. Never did like "use" 
clauses.

Interestingly, this issue reveals a benefit of unifying module and type. 
A unified model that dictates unique class names (eg. Eiffel's) simplifies 
things by allowing class names to serve a twofold purpose in clients - 
importing modules and entity (variable or routine parameter) declarations.
In one fell swoop, the need for import statements ("with"), visibility 
statements ("use"), and module prefixes for diambiguation disappear.

WRT renaming operations, I'm not sure whether the current semantics provide 
the same capability as Eiffel. For that to be the case, it would need to allow
synonyms in *declarations* as in the Eiffel declaration of the equality 
operator (overlooking the anchored type):

  equal, frozen standard_equal (some: ANY; other like some): BOOLEAN is..

[This declaration gives you a common declaration for a redefinable - "equal" -
and a non-redefinable operation - "standard_equal". In a mission-critical system,
where you wanted to force static binding, you could use the frozen version in 
calls and use the redefinable version to specialise when inheriting.]

A cursory glance at the Rationale - 8.3 suggests you may be able to do this 
but I'm not sure.

BTW, I recall reading somewhere in the Rationale that Ada allows some sort of
anchored type declaration. Anyone care to give an example?..


:> Yes, timing *is* something to be concerned about when applied to realtime 
:> systems. That's why I suggested not using assertions in the hard realtime
:> threads of a process. BTW, software designed using DBC may actually run *faster*
:> than code without it because you get to strip out all the defensive validity
:> checks. You have already ascertained during development that operations are
:> called in valid contexts so you don't have to check the context.
:
:In Eiffel that may be true provided that removal of assertion checks doesn't
:significantly affect the performance of the code in any way.  The issue of timing,
:mentioned by Ken above, is a good example).

Yes, that's particularly an issue in mission-critical HRT domains such as Ken's
(spacecraft(?)..). For domains where timing is less critical such as ours 
(simulators), it becomes a viable tool. I should reiterate (in case it's been 
forgotten) my original suggestion that individual threads *within* an HRT system 
may be medium RT and hence candidates for Eiffel-style contracting. This implies
an architecture in which threads may be allocated to specific processors of 
multi-processor hardware. In this way, the HRT threads can happily do their 
stuff without risk of interference from slower threads. This reality of this
scenario depends, of course, on the timing requirements of inter-thread 
communication.


:I imagine that one needs to take special care when using assertions in
:languages that don't fully support them.  

Definitely, and I would hope GNAT, for example, allows you to use assertions
without enclosing if-statements or compiler directives like 

  begin
    assert (<boolean_expression>)           -- precondition
    ...                                     -- actual body of routine
    assert (<other_boolean_expression>)     -- postcondition
  end;

and allows you to turn them on or off via a compiler switch. Is this true?


:From my (sorely lacking!!) knowledge
:of Eiffel, clauses that define the precondition and postcondition of an
:operation contain exactly one boolean statement which automatically restricts
:the coder from including procedural code within these sections.

Yes, the above would look like

  require <boolean_expression>              -- precondition
  do
    ...                                     -- actual body of routine
  ensure <other_boolean_expression>         -- postcondition
  end;


:While this argument favours Eiffel in terms of assertions, it doesn't
:mean that porting this functionality to Ada will not introduce other faults.

Sure. It's best to use a technique that minimises the risks - hence my 
expectation of what GNAT provides.


:With Don's demonstration of assertions last Friday (Jul 11 18:05:13 EST) the
:postcondition was implemented in the form:
:
:if <assertions on> and then <bool_postcondition>
:  raise <postcondition exception>
:end if;
:
:The implementation of the assertion is done with multiple statements, so
:there is the possibility of important sections of code being inadvertently
:added within the if-statement which would then be removed when assertions
:are disabled.

I agree and this certainly isn't my prefered way of emulating assertions. 
I would much prefer to use the technique I described above but doing so 
with our Ada83 Verdix compiler would require using compiler directives to 
wrap each assertions. As this, would be messy, I chose to use if-statements
where the conditional expression was a short-circuit boolean expression.
This represented a minimal risk to correctness (the first component is 
Assertions_On so the rest is ignored if set to False) and a small execution 
overhead acceptable for our medium RT domain.


:I have seen this happen at least once, where an executable was released to
:the test group which AFAIK was only tested with assertions enabled, and then
:it was discovered that a crucial line of code was removed because it was
:within an assertion block and once this error was encountered the executable
:didn't crash but its functionality was imparired severely enough so that
:it had to be run again.

I expect you are referring to my own error (actually it was two) in which 
I coded the incorrect logic. I hope you'll allow me a few mistakes. After all,
these were the only two extant miskakes following integration out of 172 
such statements. That implies 98.84% were logically correct which, you'll 
agree, isn't too bad. What this does reinforce is that assertions do not 
obviate the need for testing but are a tool to help facilitate it.

BTW, assuming what you say is correct, the assertions were turned off and 
the code handed over to the testers without my knowledge. I would have tested
it first.

:Even one error, however minor, is enough to warrant another round of
:testing after assertions are removed: at least for languages that don't
:fully support assertions.  

..*especially* for such languages.

:Even if no errors are discovered in the process
:I would consider it a worthwhile exercise, if only to convince myself that
:the software functions how I intended.

Certainly.

:A suggestion: to avoid some of these problems one could have written two
:procedures, say 'precondition' and 'postcondition', each having an 'in'
:boolean parameter.  Each procedure should do nothing if assertions are
:disabled, but if they are enabled then they would raise the appropriate
:exception if the 'in' parameter was false.
:
:Then rather than the above block, one could evaluate a postcondition
:by the call:
:
:postcondition(<bool_postcondition>);
:
:and similiarly for preconditions.  A sample implementation of 'postcondition'
:(in pseudo-Ada) is:
:
:--------------------------------------------------------------------------------
:
:procedure postcondition(requirement: in boolean) is
:begin
:
:# if <assertions on> then
:
:  -- check condition and raise exception if violated
:  if not requirement then
:    raise <postcondition exception;>
:  end if;
:
:# else
:
:  null;
:
:# end if;
:
:end postcondition;
:pragma INLINE(postcondition);
:--------------------------------------------------------------------------------
:
:So when exceptions are disabled (via a compiler directive), 'postcondition'
:would have a null body, and since it's inline there would be no unwanted
:procedure call.  It also means that you can conditionally compile
:assertions without having to surround each assertion with conditional
:compilation directives.

Neat idea. What a pity you didn't think of it back in February! Maybe we could 
use it next time if we don't have something better..


:Naturally, my suggestion above still fails to prevent the addition of code
:before a precondition check, or after a postcondition check, etc.

Yes, although the amount of self-discipline to use it effectively is small.
To eliminate that entirely, best use the real thing. :)


:Yes, if you know the compiler has a bug in the first place.  The trouble is
:that you don't know it's a problem until it occurs, and a compiler could
:have a subtle bug that only occurs in very particular circumstances.
:
:Although any respectable compiler has minimal bugs if any, if we don't test
:our products after assertions are suppressed then we unnecessarily transform
:our confidence in, into dependence on, the vendor's compiler to function
:correctly.

Sure. I suppose if anyone is going to emulate assertions in ways that may 
affected by compiler optimisations, it would be wise to become acquainted 
with these so you know what you're in for.


:It would be irresponsible to deliver software that has only been tested with
:assertions enabled, knowing that if an error occurs in the released version
:then it's "not my fault".  So for this reason, and for peace of mind, I would
:certainly test the version of the software to be delivered to the customer.
:Since we expect not to find more errors, this last phase would run smoothly
:and quickly.

Yes, I suspect this is usual practice.


:> :Another consequence of using assertions is that you have to develop and
:> :test the
:> :assertions. 
:> 
:> Correct. My initial reaction when I started using them was "Gee, I've got to
:> do this extra work on top of writing the "real" code! However, I found I was 
:> spending about a third of the time integrating compared with my colleagues
:> which meant I was saving time overall and producing more reliable code to boot.
:
:Why should a short integration period automatically imply code reliability?

Your right - this is mis-phrased. It should be:

  "However, I found I was spending about a third of the time integrating 
   compared with my colleagues which meant I was saving time overall. Despite
   spending less time integrating, my code was more reliable."


[...]

:BTW, how do you verify the correctness of your assertions, 

You already have a built-in assertion checking mechanism in the code proper
because if an assertion is incorrectly coded, it will raise an exception 
in *valid* circumstances rather than invalid ones. If you know that the 
context is correct, examination of the boolean expression cin the assertion 
will very quickly show you what the problem is. The upshot is that you have 
to think catefully about what the valid underlying assumptions are in the first
place and debug assertions that reveal incorrect assumptions or simply coding
errors.

:and that there are
:no errors that the assertions didn't find?  

You can't verify that of course. You can't express everything as an assertion
and their use doesn't obviate the need for testing. Rather, they help 
facilitate testing.

:Do you prefer code inspection,
:or if you do your verification by executing the program itself, how do you
:ensure that each section of code is exercised?  

Both of these. To ensure code coverage, I used the debugger to check that 
the right brancehes were executed in the right circumstances.

:Either way, a documentation
:of your method would provide a good test which can then be reproduced should
:the software be modified.

Yes, that would be a good idea. Not just now though - I have some test reports
to write!  :)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00             ` Warwick Pulley
  1997-07-17  0:00               ` Warwick Pulley
@ 1997-07-17  0:00               ` Nick Leaton
  1997-07-17  0:00                 ` Richie Bielak
                                   ` (2 more replies)
  1 sibling, 3 replies; 255+ messages in thread
From: Nick Leaton @ 1997-07-17  0:00 UTC (permalink / raw)



Warwick Pulley wrote:

stuff on implementing assertions in Ada deleted


> Example 2 above is an example how the assertions can be "mis-implemented" in
> Ada, because the logic is wrong and necessary code was included in the "if"
> statement.  As you have said, all you need in Eiffel is the boolean
> expression itself, and since Eiffel has a special clauses for these
> assertions it's not possible to include vital procedural code within these
> clauses.

Why would you want to place procedural code in an assertion? It is the
same as saying you want to have a side effect of a function. If it is
vital code, then presuably you always want it executed. Or it may
be debugging/tracing information, in which case it isn't an assertion,
but it should be placed in some form of conditional compilation or
execution block.

Separate point. One of the valid objections that has been raised with
assertions is question of execution time being different with them on
from when they are off.

From other posters, it seems that with life critical systems (avionics)
that this is an important consideration. Am I the only one who finds
this worrying, that systems you have to trust depend on some calculation
as to how the program is going to run? What happens if a new compiler
comes out that has a different optimisation technique?



-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                 ` Paul Johnson
  1997-07-17  0:00                   ` Jon S Anthony
@ 1997-07-17  0:00                   ` Stuart Palin
  1997-07-18  0:00                     ` Ian Rae
  1997-07-18  0:00                     ` Paul Johnson
  1997-07-18  0:00                   ` Joachim Durchholz
  2 siblings, 2 replies; 255+ messages in thread
From: Stuart Palin @ 1997-07-17  0:00 UTC (permalink / raw)



paul.johnson@gecm.com (Paul Johnson) wrote:

>The thing is that in Eiffel the assertions are not just a run-time error
>detection mechanism, they are also a documentation and specification
>mechanism.  The Ada assertion was invisible because it was buried in the
>implementation of the routine that failed.  An equivalent Eiffel routine
>(if it were correct) would have had the assertion in its interface, and
>so on up to the top level of the software package under discussion.  So
>anyone reusing the package would have seen the assertion.  The Inquiry
>specifically commented that the Ada assertion was buried so deeply that
>it was effectively invisible to any review.

I am not at all convinced by this Paul, in our experiences with SPARK,
where formal specifications are hoisted up through the program structure
revealing dependencies of lower level routines it is all too easy to end
up with an unmanageable number of annotations (assertions).  This means
that trying to find a possible risk like the Ariane remains impractical
using this technique since it is like looking for the proverbial needle
in a haystack.

This sort of problem would seem to be exacerbated if everyone is creating
assertions for every possible thing that could go wrong.

--
Stuart Palin
Consultant Engineer
Flight Systems Division (Rochester)
GEC Marconi Avionics Ltd
[usual disclaimers to protect the company]





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00               ` Nick Leaton
@ 1997-07-17  0:00                 ` Richie Bielak
  1997-07-17  0:00                   ` Ken Garlington
                                     ` (3 more replies)
  1997-07-17  0:00                 ` Ken Garlington
       [not found]                 ` <JSA.97Jul17174044@alexandria.organon.com>
  2 siblings, 4 replies; 255+ messages in thread
From: Richie Bielak @ 1997-07-17  0:00 UTC (permalink / raw)



Nick Leaton wrote:

[...]
 
> From other posters, it seems that with life critical systems (avionics)
> that this is an important consideration. Am I the only one who finds
> this worrying, that systems you have to trust depend on some calculation
> as to how the program is going to run? What happens if a new compiler
> comes out that has a different optimisation technique?
> 

I always thought it would be nice to have postconditions of the form:

	ensure
		execution_time < 10 -- 10 milliseconds, let's say

So an exception would be raised if the routine took too long
to execute.

...richie

-- 
* richieb@XYZZYnetlabs.net       - at home |  Richie Bielak        *
* richieb@XYZZYcalfp.com         - at work |                       *
*          Home page:   http://www.netlabs.net/hp/richieb          *
*        "Fight software piracy, use free software!" (me)          *
*        (Remove XYZZY  from my address before replying)           *




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00           ` Don Harrison
@ 1997-07-17  0:00             ` Karel Th�nissen
  1997-07-21  0:00               ` Don Harrison
  1997-07-17  0:00             ` Robert Dewar
  1997-07-17  0:00             ` Robert Dewar
  2 siblings, 1 reply; 255+ messages in thread
From: Karel Th�nissen @ 1997-07-17  0:00 UTC (permalink / raw)



Don Harrison wrote:

> Interestingly, this issue reveals a benefit of unifying module and type.
> A unified model that dictates unique class names (eg. Eiffel's) simplifies
> things by allowing class names to serve a twofold purpose in clients -
> importing modules and entity (variable or routine parameter) declarations.
> In one fell swoop, the need for import statements ("with"), visibility
> statements ("use"), and module prefixes for diambiguation disappear.

Correct, that this is unified in Eiffel, but the problem is pushed
towards Lace: in Lace you do more or less the same as with and use in
Ada.

You cannot have human-friendly names for classes/components if you also
want to use classes written by third party vendors. There just is no way
to avoid vendors from using identical symbolic names for their gadgets.
So renaming and specification of classes used remains necessary.

Groeten, Karel




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                 ` Richie Bielak
  1997-07-17  0:00                   ` Ken Garlington
@ 1997-07-17  0:00                   ` Karel Th�nissen
  1997-07-17  0:00                   ` Samuel Tardieu
  1997-07-23  0:00                   ` Don Harrison
  3 siblings, 0 replies; 255+ messages in thread
From: Karel Th�nissen @ 1997-07-17  0:00 UTC (permalink / raw)



Richie Bielak wrote:
> 
> Nick Leaton wrote:
> > From other posters, it seems that with life critical systems (avionics)
> > that this is an important consideration. Am I the only one who finds
> > this worrying, that systems you have to trust depend on some calculation
> > as to how the program is going to run? What happens if a new compiler
> > comes out that has a different optimisation technique?

> I always thought it would be nice to have postconditions of the form:
> 
>         ensure
>                 execution_time < 10 -- 10 milliseconds, let's say
> 
> So an exception would be raised if the routine took too long
> to execute.

I agree with aforementioned posters that timing dependency should be
made explicit in a formal way. In general it is not good engineering if
the correctness of a program depends in undocumented ways on the
compilers, its optimiser, the use of assertions in production code, the
clock frequency, etc.

I do agree with Ken and Robert that assertions do effect timing and
caching, so that assertions in production code may be impossible, and
that even testing with assertions included my give unpredicatable
results.

Richie's proposal has a nice property: if we include assertions during
testing, then if the additional coding affects the timing in an unwanted
way, then the timing assertion will fail and the problem is revealed. It
should be clear that in that case the system cannot be tested with
assertions switched on, and no logical assumptions as described by the
other assertions can be tested, but at least we know it, and we shall
have no suprises of unexplanable difference between testing (with
assertions) and production (without assertions).

However, it can very well be that this assertion cannot be used in the
production code for the very same reason that non-timing assertions
cannot be included.

I imagine that in avionics the code is made for a very specific hardware
configuration and with a very well defined set of development tools. 
So the dependency on compiler, hardware platform, etc., may not be a
problem there. This difference has other consequences, I understood from
Ken. A programmer for say an IS is not designing for a particular
platform, so assumptions can sometimes be necessary, and should then be
documented (possibly with assertions that are propagated up). However,
with avionics, everything is known in advance so there is no reason to
make assumptions about the platform and tools. The same thing applies to
the specifications of the other systems in the plain it is connected
with:  assumptions are never wanted and never necessary.

Groeten, Karel




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00             ` Ken Garlington
@ 1997-07-17  0:00               ` "Paul E. Bennett"
  1997-07-17  0:00                 ` Robert Dewar
  0 siblings, 1 reply; 255+ messages in thread
From: "Paul E. Bennett" @ 1997-07-17  0:00 UTC (permalink / raw)



In article <33CD6512.2404@flash.net> kennieg@flash.net "Ken Garlington" writes:

[Lots of stuff re-opening the Ariane/DBC/Eiffel arguments deleted]
 
> Unfortunately, it's already been re-opened. As I feared, people are
> using your paper to "prove" the worth of DBC/Eiffel in safety-critical 
> systems, although no one has yet published a list of such systems that 
> have been written in Eiffel.

It is a shame that Les Hatton is not on this ng. He is a very interesting 
character who has spent quite some time examining the effect of language, 
project size, complexity and domain expertise on the outcome of various
projects. From his results (and supported by numerous other papers) it
appears that the most important factor in understanding a project is the
level of domain expertise in the project. The language used had very little
effect on the projects studied in terms of quality.

The other main determinate of project outcome is the nature of the projects 
management. Domain expertise might be difficult to build into any programming 
language unless you are willing to invest very heavily in your programmers 
domain specific tools which will need construction by domain experts anyway.

On the other hand, improving the project management can be done with improved
management training, provision of general and specific management tools and
instillation of "High Integrity Culture" within an organisation.

Now it should be time to end the language wars and look at what we can all 
learn from each other.

-- 
Paul E. Bennett ................... <peb@transcontech.co.uk>
Transport Control Technology Ltd.   <http://www.tcontec.demon.co.uk/>
+44 (0)117-9499861                  <enquiry@transcontech.co.uk>
Going Forth Safely





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-07-17  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  1997-07-17  0:00 ` Samuel Mize
  0 siblings, 1 reply; 255+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-07-17  0:00 UTC (permalink / raw)



Jean-Marc Jezequel <jezequel@IRISA.FR> writes:
>At the risk of repeating myself, and reopening a thread beaten to death,
>the all point of design by contract (DBC) is to
>make this kind of assumptions explicit. Ariane 5 is just a nice striking
>example
>of working with assumptions that are true at a point in time (Ariane 4) and no
>longer
>later on (Ariane 5). I think we agreed on this previously.
>
>To sum up your point, you think that DBC, i.e. expressing hidden assumptions
>with
>Eiffel-like assertions would not have been practicable in this case.
>Others think it would have...
>
    At the risk of butting in and helping to start the beaten-to-death
    thread once again...

    The Ariane software specifically and very deliberately *removed*
    the checks because of time constraints. Ada would have normally
    conducted the checks because of range constrainst. (Wouldn't help
    unless the programmer put in an exception handler) Eiffel could
    have performed the checks. (Assumes the programmer would have put
    in the assertions) One could even argue that C would have done the
    job in the hands of a "competent" C programmer who would have
    bothered to check the input parameters or create an ISR to handle
    the overflow.

    In this case, the language is *not* an issue and never was. It was
    an issue of the engineering decisions to deliberately remove the
    safety device combined with the management decision to reuse the
    software in a new environment without any additional testing.

    An associate of mine once said in the heat of a language war:
    "Languages don't kill people... Programmers do!" Yes, language
    features may support safety - but ultimately it's the programmer's
    job (manager's job?) to get it right.

    MDC

Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
===============================================================================
    "A government that is big enough to give you all you want is big
    enough to take it all away."
        --  Barry Goldwater
===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                 ` Richie Bielak
  1997-07-17  0:00                   ` Ken Garlington
  1997-07-17  0:00                   ` Karel Th�nissen
@ 1997-07-17  0:00                   ` Samuel Tardieu
  1997-07-17  0:00                     ` Richie Bielak
  1997-07-23  0:00                   ` Don Harrison
  3 siblings, 1 reply; 255+ messages in thread
From: Samuel Tardieu @ 1997-07-17  0:00 UTC (permalink / raw)



>>>>> "Richie" == Richie Bielak <richieb@XYZZYcalfp.com> writes:

Richie> I always thought it would be nice to have postconditions of
Richie> the form:

Richie>   ensure
Richie>     execution_time < 10 -- 10 milliseconds, let's say

Richie> So an exception would be raised if the routine took too long
Richie> to execute.

Well, I find the corresponding Ada code readable enough:

   select
      delay 0.010;               --  The 10ms you were talking about
      raise Timeout_Failure;     --  Raise an exception, or do anything else
                                 --  you need (use a fast version of
                                 --  your computation for example).
   then abort
      [...your code here...]     --  This piece of code will be
                                 --  aborted if it is not terminated within
                                 --  the 10ms you required above.
   end select;

And I don't think this should be a pre or post-condition, since it is
not something which will be checked at the beginning or at the end of
the job, but something which will indirectly interact with it (the job
will be potentially aborted).

  Sam
-- 
Samuel Tardieu -- sam@ada.eu.org




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                   ` Samuel Tardieu
@ 1997-07-17  0:00                     ` Richie Bielak
  1997-07-23  0:00                       ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Richie Bielak @ 1997-07-17  0:00 UTC (permalink / raw)



Samuel Tardieu wrote:

[...]
> 
> Well, I find the corresponding Ada code readable enough:
> 
>    select
>       delay 0.010;               --  The 10ms you were talking about
>       raise Timeout_Failure;     --  Raise an exception, or do anything else
>                                  --  you need (use a fast version of
>                                  --  your computation for example).
>    then abort
>       [...your code here...]     --  This piece of code will be
>                                  --  aborted if it is not terminated within
>                                  --  the 10ms you required above.
>    end select;
> 

That's neat. Except that a postcondition will be part of the contract
(i.e. specification) for the routine, so the caller will know what to 
expect. Your code is part of the implementation.

When you are using someone else's component you usually don't want
to look at the source.

...richie

-- 
* richieb@XYZZYnetlabs.net       - at home |  Richie Bielak        *
* richieb@XYZZYcalfp.com         - at work |                       *
*          Home page:   http://www.netlabs.net/hp/richieb          *
*        "Fight software piracy, use free software!" (me)          *
*        (Remove XYZZY  from my address before replying)           *




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00           ` Don Harrison
  1997-07-17  0:00             ` Karel Th�nissen
  1997-07-17  0:00             ` Robert Dewar
@ 1997-07-17  0:00             ` Robert Dewar
  1997-07-18  0:00               ` Jon S Anthony
  1997-07-21  0:00               ` Don Harrison
  2 siblings, 2 replies; 255+ messages in thread
From: Robert Dewar @ 1997-07-17  0:00 UTC (permalink / raw)



Don Harrison says

<<Yes, I should have realised! It's the old workaround to the infuriating Ada83
visibility problem of not being able to see the predefined operators of a user-d
efined(?) type in client code. In spite of already with-ing the
supplier module (which I don't think you should have to do, anyway - if you
*use* features exported by a package, explicitly importing it is redundant),
you can't see (hence, use) the imported operators.
>>


My goodness, surprising that anyone would think this, but then I guess there
are people who really prefer uncontrolled anarchy.

To me one of the real advantages in Ada is that you know right away, right
at the start of the package, exactly what services are being used, and
you can more easily excercise control over this. If you let code anywwhere
reach anywhere easily, you have a recipe for mess.

The requirement to write a with clause is also the requirement to think
about whether it is appropriate for the unit you are in to "with" the
unit that you think you need.

As for the "infuriating" Ada 83 visibility "problem". I always found this
odd. I understand that people do not like to use "use" because, especially
with poor tools, they want to be easily able to tell where somethintg
comes from, but I never understood why this perfectly understandable
reasoning does not apply to operators (personally I prefer to use "use"
most of the time anyway).





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00           ` Don Harrison
  1997-07-17  0:00             ` Karel Th�nissen
@ 1997-07-17  0:00             ` Robert Dewar
  1997-07-22  0:00               ` Don Harrison
  1997-07-17  0:00             ` Robert Dewar
  2 siblings, 1 reply; 255+ messages in thread
From: Robert Dewar @ 1997-07-17  0:00 UTC (permalink / raw)



Don said

<<Interestingly, this issue reveals a benefit of unifying module and type.
A unified model that dictates unique class names (eg. Eiffel's) simplifies
things by allowing class names to serve a twofold purpose in clients -
>>


Time to restate the following observation:

Unify and Confuse both mean at their root the same thing, namely to
make into one, or to join together, but they express a different
judgment as to the desirability of of the joining.

A lot of the arguments in PL design come doesn to whether joining concepts
together is unification or confusion:

Do expression languages unify or confuse the notion of statement and
expression?

Does Algol-68 unify or confuse the notion of reference and pointer

Does Eiffel unify or confuse the notions of module and type

TO me the answer to the last question is that it confuses, rather than
unifies, quite contrary to Don's point of view. And it is hardly worth
going through the aguments again, since there is unlikely to be anything
new said (Don certainly had nothing new to say on this issue, and neither
do I :-)





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00               ` "Paul E. Bennett"
@ 1997-07-17  0:00                 ` Robert Dewar
  0 siblings, 0 replies; 255+ messages in thread
From: Robert Dewar @ 1997-07-17  0:00 UTC (permalink / raw)



<<It is a shame that Les Hatton is not on this ng. He is a very interesting
character who has spent quite some time examining the effect of language,
project size, complexity and domain expertise on the outcome of various
projects. From his results (and supported by numerous other papers) it
appears that the most important factor in understanding a project is the
level of domain expertise in the project. The language used had very little
effect on the projects studied in terms of quality.
>>


Well I certainly disagree strongly with Les' quite bogus conclusions about
language complexity drawn from the number of isses raised with respect to
the standard. I can't comment on his other observations. There is certainly
a body of literature showing that language *does* matter, and particularly
the abstraction level of a language matters. 

Actually I think these studies are all dubious, it is almost impossible
to do controlled studies of any kind, so this kind of work ends up being
very soft, almost as bad as a lot of wooly social science stuff. People
almost always seem to find the data that supports their preheld conceptions,
always an indication that you are treading on flaky areas from a scientific
point of view.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00 ` Samuel Mize
@ 1997-07-17  0:00   ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-17  0:00 UTC (permalink / raw)



Samuel Mize wrote:
> 
> The Ariane crash proves that properly-managed DBC would be
> better than DBMG (Design By Management Guesswork).  It neither
> supports nor refutes the thesis that DBC is better than other
> responsible/traditional engineering methods.
> 
> I can't say that Meyer et al. intended to imply otherwise, but
> it is certainly a reasonable inference for the reader to draw,
> given the paper.  That inference angered some people.

By the way, if anyone wants to read the two papers for themselves:

Ariane V final report:

   http://www.esrin.esa.it/htdocs/tidc/Press/Press96/ariane5rep.html

Eiffel paper on Ariane V:

  
http://www.eiffel.com/doc/manuals/technology/contract/ariane/index.html

which contains the now-infamous quote:

   "Does this mean that the crash would automatically have been
   avoided had the mission used a language and method supporting
built-in
   assertions and Design by Contract? Although it is always risky to
draw
   such after-the-fact conclusions, the answer is probably yes:"

Note the term "language and method." As explained later in the paper,
only Eiffel meets the required criteria. Both are required, per Meyer.

> 
> Samuel Mize




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00 Marin David Condic, 561.796.8997, M/S 731-96
@ 1997-07-17  0:00 ` Samuel Mize
  1997-07-17  0:00   ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Samuel Mize @ 1997-07-17  0:00 UTC (permalink / raw)



Marin David Condic, 561.796.8997, M/S 731-96 wrote:

> The Ariane software specifically and very deliberately *removed*
> the checks because of time constraints.

Correct me if I'm wrong.

My understanding from the previous threads was that there was
a specific management decision to not consider Ariane 5
requirements for the Ariane 4 INS design.  The check removal
was reasonable in the Ariane 4 context.

Then there was a specific management decision to not review
for Ariane 5 the requirements to which the INS was built, or
to retest it in the new conditions.

Given these decisions, the problem would not have been caught,
no matter what assertions were in the code.

Now, Meyer et al. never stated outright that using Eiffel (or
assertions) would have prevented the crash; they stated that
using Design By Contract (DBC) would prevented the crash.

This is trivially true.  Traditional methods of specification
review or design review or test would ALSO have prevented the
crash.  Saying "DBC could have prevented the crash" creates a
misleading suggestion that this demonstrates a DBC advantage
over other methods.

The Ariane crash proves that properly-managed DBC would be
better than DBMG (Design By Management Guesswork).  It neither
supports nor refutes the thesis that DBC is better than other
responsible/traditional engineering methods.

I can't say that Meyer et al. intended to imply otherwise, but
it is certainly a reasonable inference for the reader to draw,
given the paper.  That inference angered some people.

Samuel Mize




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                 ` Paul Johnson
@ 1997-07-17  0:00                   ` Jon S Anthony
  1997-07-17  0:00                   ` Stuart Palin
  1997-07-18  0:00                   ` Joachim Durchholz
  2 siblings, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-17  0:00 UTC (permalink / raw)



In article <5qklt1$4el$2@miranda.gmrc.gecm.com> paul.johnson@gecm.com (Paul Johnson) writes:

> Whilst I don't agree with Meyer that Eiffel would probably have prevented
> the Ariane crash

Agreed, :-)

, he does have a point.

No, he does not.  Well, actually he does - editors can be fooled into
passing off simple advertising for real articles.


> The thing is that in Eiffel the assertions are not just a run-time error
> detection mechanism, they are also a documentation and specification
> mechanism.  The Ada assertion was invisible because it was buried in the
> implementation of the routine that failed.  An equivalent Eiffel routine
> (if it were correct) would have had the assertion in its interface, and
> so on up to the top level of the software package under discussion.  So
> anyone reusing the package would have seen the assertion.  The Inquiry
> specifically commented that the Ada assertion was buried so deeply that
> it was effectively invisible to any review.

The problems with this view are truly overwhelming.  It's hard to even
know how to begin or what to say in this sort of informal setting.

Here's a sampling:

1. The sort of "assertion" in this specific case could have been
explicitly coded as for the "equivalent Eiffel routine".

2. This level of assertion (range constraint) could be specified in
the interface of the routine.

3. This level of assertion would be inherited if any types were
derived from the type specifying it (just like in Eiffel).

4. So, for this case, Eiffel brings absolutely nothing to the table
that wasn't readily available to the Ada programmers.  Nothing.  Zero.
Nada.  Zilch.

5. The engineers and programmers knew all about this capability.  In
fact such an explicit assertion with an attendant exception handler
was even in place at one point.

6. The engineers concluded that _for the context of intended use_
(Ariane IV launches) this condition _could not occur_ unless the
_physical_ system had catestrophically failed.

7. Like _good_ engineers, this therefore _useless_ explicit check was
removed in order to free up some cycles that could be used on
something that _was_ worth processing.

8. Such contextual semantics of intended use settings are extremely
problematic to codify using standard formal methods (assertions,
functional representation, etc.  things like Z, LARCH, ZD, etc.).
There is even reason to believe that this is not even _possible_, let
alone practical.

9. For some reason, many "formal method advocates" still don't get
this - despite 15+ years of overwhelming evidence to the contrary.
This obstinacy is reminescent of the GOFAI camp who thought all you
had to do to get intelligence was hang a frame system (or some other
such symbolic representation) off an NL parser.  There was a lot of
"and Bob's your Uncle" talk coming out of them too.

10. Setting reason aside and attempting to annotate "components" with
such ancillary semantic information just results in huge amounts of
difficult to manage and typically irrelevant information.  The result
is the usual "information overload" which can actually tend to
_obscure_ real problems.

11. Even trying to come up with the "correct" annotations apriori is
an extremely suspect activity.  Any given context of use is so
overwhelming complex and multifaceted, that trying to codify it by
means of such one dimensional micro level detail is a lost cause.
This is a lesson that FMs would be wise to take from the knowledge
representation school of hard knocks.

12..oo, and on and on...


> Where this argument falls down, I'm afraid, is that the package did not
> receive its data from another software package, but from a hardware
> sensor.  At this point the whole idea breaks down.  A pity.

This doesn't even scratch the surface of why this view is bogus.


/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00         ` Joachim Durchholz
@ 1997-07-17  0:00           ` Ken Garlington
  1997-07-17  0:00           ` Robert Dewar
                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-17  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:
> 
> Steve Furlong wrote:
> > get or free memory. If your process _must_ check ports every 10 ms,
> > you can't be waiting half a second for memory compaction.
> 
> Arrgh! Will that idea nevere go away!!
> The best available GC algorithms don't go away for compacting; they run
> in parallel with the normal program (as a coroutine if you don't want a
> preemptive scheduler).

How does GC run "in parallel" on a uniprocessor implementation?

I assume you mean that it can be run in a separate process, but that's
not
a concern. More interesting questions to ask about these algorithms are
(for example):

1. What is the longest "critical section" (a section that cannot be
pre-empted) within these GC algorithms?

2. If the GC process is given the lowest priority, how long can it be
"starved" before memory allocation problems occur?

3. If the GC process is not given the lowest priority, what is the
likelihood that a lower priority process will be starved?

4. How much overhead will be used in swapping this process in and out
sufficiently often to keep sufficient memory available?

> 
> > Modern GC presumably can get around that problem,
> 
> That reads "definitely", not "presumably". The algorithms are there.
> Besides, hand-crafted GC may look nice on paper, but it's usually less
> efficient than automatec GC.
> Manual deallocation means programmers will pass around more copies of
> objects, defeating the very reason why automated GC isn't used. (The
> reason is that, if the programmer would just pass the reference, the
> owner of the object has to worry wether that reference he gave aways is
> still in use somewhere. If the object is copied, the owner can
> deallocate the original and doesn't have to worry about the copy - but
> the copying process itself may be more machine cycles than what would
> have been necessary to reclaim the single object with automated GC.)
> 
> > but the purveyors
> > presumably can't prove its efficacy and response time to the
> > satisfaction of the FAA and other safety hard-noses.
> 
> Well, I'm feeling cynical today, so I'd say that the safety gurus just
> don't know or care about the algorithms, because it's something new and
> they'd have to *think*. (There is a surprising number of non-engineers
> in any bureaucratic body.)

Or, perhaps the people have enough problems analyzing time effects in
a safety-critical system to have to worry about another process, one
with potentially variable effects depending upon heap utilization
at different points in the program.

> 
> Regards,
> Joachim
> --
> Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00               ` Nick Leaton
  1997-07-17  0:00                 ` Richie Bielak
@ 1997-07-17  0:00                 ` Ken Garlington
       [not found]                 ` <JSA.97Jul17174044@alexandria.organon.com>
  2 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-17  0:00 UTC (permalink / raw)



Nick Leaton wrote:
> 
> From other posters, it seems that with life critical systems (avionics)
> that this is an important consideration. Am I the only one who finds
> this worrying, that systems you have to trust depend on some calculation
> as to how the program is going to run? What happens if a new compiler
> comes out that has a different optimisation technique?

Our rule of thumb is that any significant change to the code generation
toolset requires a complete re-execution of the tests/analyses
associated
with the software. We prefer to "freeze" toolset versions at certain
points in the development process for this reason.

> 
> --
> 
> Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00         ` Joachim Durchholz
  1997-07-17  0:00           ` Ken Garlington
@ 1997-07-17  0:00           ` Robert Dewar
  1997-07-18  0:00           ` John Nagle
  1997-07-18  0:00           ` Jon S Anthony
  3 siblings, 0 replies; 255+ messages in thread
From: Robert Dewar @ 1997-07-17  0:00 UTC (permalink / raw)



J Durchholz said

<<Arrgh! Will that idea nevere go away!!
The best available GC algorithms don't go away for compacting; they run
in parallel with the normal program (as a coroutine if you don't want a
preemptive scheduler).
>>


All very well, and a loud minority has been yelling this for a while :-)

But what would be convincing would be actual examples of critical real
time programs that use this kind of concurrent garbage collection
successfully. Typically in the past we have often seen posts of this
kind based on best understanding of current theory, but we have not
seen much in the way of real life experience articles!





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                 ` Richie Bielak
@ 1997-07-17  0:00                   ` Ken Garlington
  1997-07-23  0:00                     ` Don Harrison
  1997-07-17  0:00                   ` Karel Th�nissen
                                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-17  0:00 UTC (permalink / raw)



Richie Bielak wrote:
> 
> Nick Leaton wrote:
> 
> [...]
> 
> > From other posters, it seems that with life critical systems (avionics)
> > that this is an important consideration. Am I the only one who finds
> > this worrying, that systems you have to trust depend on some calculation
> > as to how the program is going to run? What happens if a new compiler
> > comes out that has a different optimisation technique?
> >
> 
> I always thought it would be nice to have postconditions of the form:
> 
>         ensure
>                 execution_time < 10 -- 10 milliseconds, let's say
> 
> So an exception would be raised if the routine took too long
> to execute.

Of course, you have to decide if "execution time" includes the time for
the postcondition (including any code that executes after the actual
test instruction)!

We usually have such measurements _outside_ the code sequence being
measured (i.e., in the scheduler).

> 
> ...richie
> 
> --
> * richieb@XYZZYnetlabs.net       - at home |  Richie Bielak        *
> * richieb@XYZZYcalfp.com         - at work |                       *
> *          Home page:   http://www.netlabs.net/hp/richieb          *
> *        "Fight software piracy, use free software!" (me)          *
> *        (Remove XYZZY  from my address before replying)           *




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-07-18  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  0 siblings, 0 replies; 255+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-07-18  0:00 UTC (permalink / raw)



Samuel Mize <smize@LINK.COM> writes:
>Correct me if I'm wrong.
>
>My understanding from the previous threads was that there was
>a specific management decision to not consider Ariane 5
>requirements for the Ariane 4 INS design.  The check removal
>was reasonable in the Ariane 4 context.
>
    I read the report some time ago and memory fades - but my
    recollection is that they needed to gain some speed and decided to
    do so by removing the runtime checks. However, they performed an
    analysis first which indicated that across the entire Ariane 4
    flight profile, the routine could not see any numbers big enough
    to cause the error. The mistake was in accepting Ariane 4 code for
    Ariane 5 and *presuming* that it was going to work just fine
    without checking it out across the Ariane 5 flight profile.

>Now, Meyer et al. never stated outright that using Eiffel (or
>assertions) would have prevented the crash; they stated that
>using Design By Contract (DBC) would prevented the crash.
>
    Point taken. But it still seems to me that the software design was
    100% adequate in it's original context. (And the keyword here is
    "adequate" - "good enough" is not nearly so wonderful a thing a
    "perfect", but it's "good enough!") The mistake was to accept what
    was an adequate design in one context and presuming it would work
    fine without retesting it in the new environment. An analogy would
    be if I designed a wheel for a Honda Civic and then presumed
    (because wheels are wheels, right?) that I could mount the same
    wheel on a Lincoln Towncar. It might even work for a while until I
    took a really tight turn and the excess weight caused it to fail.
    Hence the fault was not with the design methodology - whatever
    methodology was originally used (including design by Ouija board,
    if you like) was *adequate* to produce a working product. The
    failure lies in the management decision - for which I'm sure
    someone caught some serious heck.

    MDC

Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
===============================================================================
    "A government that is big enough to give you all you want is big
    enough to take it all away."
        --  Barry Goldwater
===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00           ` John Nagle
@ 1997-07-18  0:00             ` Jon S Anthony
  0 siblings, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-18  0:00 UTC (permalink / raw)



In article <nagleEDI407.ABs@netcom.com> nagle@netcom.com (John Nagle) writes:

> >> Modern GC presumably can get around that problem,
> 
> >That reads "definitely", not "presumably". The algorithms are there.
> 
>      If only the Java people would use them.

:-)!  To be fair (to GC), with respect to any (all the!!!) problems of
efficiency, efficacy or robustness in Java, GC is the _least_ of its
worries!

/Jon

-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
       [not found]                 ` <JSA.97Jul17174044@alexandria.organon.com>
  1997-07-18  0:00                   ` Nick Leaton
@ 1997-07-18  0:00                   ` Joachim Durchholz
  1 sibling, 0 replies; 255+ messages in thread
From: Joachim Durchholz @ 1997-07-18  0:00 UTC (permalink / raw)



Jon S Anthony wrote:
> Unless you are using a pure functional or declarative language, you
> are writing "procedural" code.  Eiffel is about as close to either of
> these as Ada or Pascal or C.  So, if you are writing your assertions
> in Eiffel, you are writing procedural code.
> 
> If you really do want functional code - go use a _functional_
> language!

Sorry, this is plain wrong.
Assertions are indeed considered functional ("applicative" according to
Bertrand's nomenclature) in Eiffel.
I'm pretty sure that the reason is that assertions aren't intended to do
anything - they just specify conditions that have to be true at certain
points in execution. There isn't much procedural one could (or should)
do here.

Regards,
Joachim
-- 
Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00         ` Wes Groleau
  1997-07-15  0:00           ` Ken Garlington
  1997-07-16  0:00           ` Don Harrison
@ 1997-07-18  0:00           ` Robert I. Eachus
  1997-07-21  0:00             ` W. Wesley Groleau x4923
  2 siblings, 1 reply; 255+ messages in thread
From: Robert I. Eachus @ 1997-07-18  0:00 UTC (permalink / raw)



In article <33CBBF4B.7BAF@pseserv3.fw.hac.com> Wes Groleau <wwgrol@pseserv3.fw.hac.com> writes:

  > Here we go again with this myth.  Probably won't help, but I'll say 
  > one more time what others said over and over: telling people to 
  > assert or document everything pertinent will NOT cure the failure 
  > to recognize what's pertinent!!

  True, but that didn't apply to the Ariane 5 case.  If you resuse
software in an environment with very different requirements, and you
don't do anything validate the code against the new requirements and
in fact, don't do with the code--not even recompile it--and you don't
do any testing--to old or new requirements--nothing with the possible
exception of unadulterated good fortune can save you from the effects
of your blunders.

  The Ariane 4 code was provably correct and acted in accordance with
its design specification.  However, when used in an Ariane 5, that
spec effectively said, "Destroy the stack at T+38 seconds, but send
real good diagnostic data while doing it!"  (Actually, they had some
good fortune.  A gust of wind sooner could have caused the same
catastophe closer to the ground, where the likelihood of fatalities
would have been much higher.)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00                   ` Paul Johnson
  1997-07-18  0:00                     ` Jon S Anthony
@ 1997-07-18  0:00                     ` Ken Garlington
  1997-07-21  0:00                       ` Paul Johnson
  1 sibling, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-18  0:00 UTC (permalink / raw)



Paul Johnson wrote:
> 
 How?  It sounds like you would have to have internal and external
> versions of all routines, all suitably redefined in the presence of
> inheritance.  This is not a trivial suggestion.

Seems fairly trivial to me, particularly since I only have to worry
about this in certain cases.

> >So, other than maybe writing a little less code, what's
> >the significant advantage of this approach? Is it safer to not enforce
> >assertions for intra-class dependencies?
> 
> Suppose I have an invariant in my class: "foo (a, b) = 0"
> 
> This states a relationship between a and b.
> 
> Now my class could have one routine which computes both a and b
> simultaniously.  Or it could have one routine which computes a, and
> another routine which computes b.  This is purely an internal
> implementation decision, so I should be able to chose either.
> 
> But if I have in my class the following two lines
> 
>    compute_a;
>    compute_b;
> 
> then under your scheme I will get an exception.  As "compute_a" terminates,
> the invariant will be checked, and will fail.  So the public assertion
> constrains the private implementation.
> 
> (Actually, its even worse.  If I assign to a and then call any
> routine before assigning to b then I'll trip the invariant check)

Since I can structure me system to only perform the invariant from
an external call, this doesn't seem to be a big issue...

> 
> >I still don't see the big advantage from a safety-critical
> >perspective...
> 
> The Eiffel rules for assertion checking allow the software to be laid out
> in the most logical manner, making proper use of functions and procedures.
> This helps the programmers avoid bugs.

But that's an argument from assertion checking in general (which
Ada also supports). What's the big deal about having to write a
little extra code to only have certain assertions exercised from
external calls? The only difference is that Ada does internal
checks by defaults, Eiffel requires extra code if you want the internal
checks.

> 
> >> >Why would I have to duplicate assertions?
> >>
> >> Because of the Liskov Substitutability Principle.
> >
> >To expand: Why do I have to duplicate assertions _in Ada_?
> 
> Well, Ada these days has inheritance.  If you want to write correct
> software then descendants must inherit their ancestors contracts.
> If you want to check and document this then you have to write the
> appropriate assertions.

You have to write the appropriate assertions in the ancestor, in
either Ada or Eiffel.

To repeat: Why do I have to _duplicate_ assertions in Ada?

> >> In many compilers, if you say "assert: require = (a > b)" then the compiler
> >> will observe that the value of "require" is not used thereafter, and
> >> remove the statement.
> >
> >Since this isn't Ada, I couldn't comment.
> 
> This discussion started when someone (I assumed it was you, sorry I didn't
> check) proposed a type "require" defined as a subrange of Boolean constrained
> to be true.  The above statement declares a variable "assert" of type
> "require" and initialises it to "(a > b)".  If this expression evaluates to
> false then a range exception will be triggered.

ah... assert : require := (a > b);

However, this shouldn't be optimized out if an exception is possible, I
don't think. (I'd have to go look back at chapter 11 to be sure...)

>  Sorry if I've got the
> syntax wrong, and sorry that my explanation was wrong as well: I should have
> said "... the value of 'assert' is not used thereafter ...".
> 
> Of course there are other ways of writing assertion checks in Ada.
> 
> >> The whole point of Eiffel assertions is that in a correct program they
> >> have no effect on execution.  Therefore you get exactly the same results
> >> whether they are enabled or not.
> >
> >This would require (a) no changes in timing
> 
> If your software depends upon timing for the correctness of its results
> then I would certainly not want to see your software used in safety
> critical applications.
> 
> I agree that timing variations can cause different results, but why would
> they cause incorrect results?

Because you made a mistake, of course! A mistake which will be hidden
during
your testing, but become (potentially fatally) obvious during
operational use.
This is considered a Bad Thing.

>  If they don't cause incorrect results then
> why are you worried?

Because I won't know whether or not the actual system is correct or not!

> >and (b) zero probability
> >that the compiler generates incorrect code with a certain combination of
> >compiler switches and code. I am skeptical.
> 
> What does this have to do with the problem under discussion?  I agree that
> this can happen, but why does the ability to enable and disable assertions
> cause any new problems?

Because I have seen compilers that generate correct code with one set of
compiler options enabled, and a different (incorrect) set with a
different
set of options enabled. As with the timing issue above, I can do all of
my testing with assertions enabled, and have no clue whether or not the
code will still work after I disable those assertions (due to a compiler
bug). Again, this is a Bad Thing for safety-critical systems.

> 
> >> Apart from assertion exceptions, the only way that the execution of an
> >> assertion can make a difference is if you call a function with side effects.
> >> Eiffel functions are specifically banned from having side effects.
> >
> >See above.
> 
> Functions that might have side effects are fairly easy to detect (they
> assign to non-local variables, or call other routines that do so).  This
> can be statically checked.
> 
> Sometimes a function will cache a result for future use.  I've written
> table classes that do this.  Such functions are fairly rare.  When detected
> by static checks they can either be inspected carefully or simply banned.
> 
> >> Of course, you *can* leave them enabled, but it slows down your code.
> >
> >It does something else. It requires you to decide what to do if the
> >assertion is violated during execution.
> 
> Surely the same arguments apply to Ada?  Look at Arianne 5.

Yes, they certainly do (and I have applied them to Ada in comp.lang.ada
in the psat). Of course, this discussion isn't about Ada vs. Eiffel, is
it?
It's about the usefulness vs. the risks of using assertions in safety-
critical real-time systems. Eiffel claims it's big advantage over other
languages (including Ada) in this domain is stronger assertions. This is
not a particularly useful claim if there are serious problems with using
assertions extensively in such systems, is it?

> 
> >> Some people
> >> leave preconditions on in production code as well, if there are no speed
> >> problems as a result.
> 
> >What do they do if the assertion is violated?
> 
> Depends on the application.  Generally they print an error report, dump
> stack information to a file, and ask the user to phone the vendor.  Note
> that I am not proposing this for real-time embedded applications.  However
> there are safety-critical applications which are not real-time.

True. Furthermore, there are safety-critical real-time applications that
are not required to be fail-operational. In both cases, I can at least
see
the glimmer of hope that assertions might have some value. (However,
even
a non-real-time system monitoring a nuclear power plant, for example,
might
not want to print out a message saying "phone the vendor, and I hope the
reactor doesn't go supercritical while you're on hold :)

However, for _at least_ certain classes of safety-critical systems, this
behavior is completely unacceptable. Unfortunately, most people who
advocate
liberal use of exceptions are working on systems where it is quite
acceptable.

> 
> >> >> [Difficulty of getting "short-flat" forms]
> 
> >You haven't read my Ada specs!
> 
> Are you saying that you write the contract in comments in the spec?  If
> so then good for you: its good practice.  The problem is that you have
> now duplicated the information: one copy is in comments, and the other
> is in the assertions in the code. 

Actually, no: the public (abstracted) view of the assertion is in the
spec,
the implementation is in the code. This allows me to change the
implementation
any way I want without affecting the client, so long as I meet the
_requirement_
for the assertion.

> Hence you have doubled the associated
> work, and increased the risk of an error.  Eiffel requires that you write
> the contract once, and uses the text for both purposes.

Which is less writing, but may also require the user to see details that
are not necessary. (There's no obvious "best" answer here in my mind,
but
both approaches seem to be satisfactory from a safety standpoint.)

The other advantage in comments is that they won't affect the object
code. Thus, I can put in a user constraint, but not enforce it in the
code,
if I want. (I can enforce it in other ways; e.g. in a debugging
environment). This allows me to compromise between no assertion
capability
at all, and having assertions that affect my object code in unwanted
ways.
Particularly for complex constraints, comments may actually be more
safe in this environment. (Simple constraints, of course, can be coded
in
type information and checked statically, even if no dynamic checking is
done.)

> 
> I'll agree that all of the benefits of Eiffel assertions are available
> in Ada if you put in enough work, but why all this effort to do something
> that Eiffel does automatically?

As noted before, there doesn't seem to be much difference in the Ada
work
vs. the Eiffel work, particularly since there are limitations to the
amount of assertions to be embedded in the code for safety-critical
systems.

>  Also if the work becomes too onerous
> then it tends to get dropped when schedule and budget pressure is on.
> This has been the vice of software engineering ever since the discipline
> was invented.  Eiffel makes good practice so cheap, easy and obvious
> that people do it without needing to make a special point of it.

However, this extra capability does me no good if I can't take advantage
of it.

> 
> [Stuff about deriving documentation from specs deleted: we seem to be in
> broad agreement]
> 
> Paul.
> 
> --
> Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
> +44 1245 242244         +-----------+-----------------------------------------+
> Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
> Home: <Paul@treetop.demon.co.uk>    | standards, all different.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00           ` Don Harrison
@ 1997-07-18  0:00             ` Ken Garlington
  1997-07-22  0:00               ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-18  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> :> :> Maybe general assertions are more common than you imagine. However, I agree
> :> :> that range constraints are roughly covered by Ada subtypes. I use them liberally
> :> :> for just that purpose.
> :> :
> :> :Maybe, but again, I would like to see how these complex assertions are
> :> :used.
> :>
> :> You would use them anywhere that a piece of code makes assumptions. For example,
> :> to help avoid the Ariane fiasco, include contracts in the INS(?) that specify
> :> Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
> :> you apply Ariane 5 dynamics to it.

An assertion violation... as in Operand_Error?

Again, someone needs to explain how these high-level assertions would
have
benefitted the Ariane 5 IRS.

> So, here's a different example. In my key handling object (one of the highest
> level in the simulation), there's an operation for interpreting the CLEAR key.
> Simplifying a little, pressing this key should reactivate the menu, clear the
> key sequence and clear any menu or sub-menu selection. So, there's a compound
> postcondition thus:
> 
>       if SA.ASSERTIONS_ON and then (INPUT_STATE /= MENU or else
>         NO_OF_KEYS /= 0 or else MENU_OPTION_SELECTED or else
>         SUBMENU_OPTION_SELECTED) then
>         raise SA.POSTCONDITION_ERROR;
> 
> Note that some of the components are functions. Wrapping them in this way
> is typical practice in Eiffel and enables you to use them elsewhere (eg. in
> if-statements in the code proper) and makes contracting scalable.

In Eiffel, I assume this code would be in the "short form." Is the
user/reviewer
really expected to read all of this (including looking up the functions
embedded
in this code) and understand it?

Wouldn't it be just as easy to say, in the description of this
operation, the
English text preceding it?

> 
> Clearly, the assumptions weren't properly thought out. Getting them right
> would have made the difference.

Keep in mind that the people making these assumptions were not
programmers -
they were system engineering types. So, unless you propose teaching DBC
to all engineers in the program (which might not be a bad idea,
actually),
then 

> :According to Meyer, et. al. Eiffel programmers would have written the
> :handler
> :differently, and also they would have known to do the testing
> :differently (even though
> :the requirements specification said that the tests need not change).
> 
> I don't know about you, but I tend to take a pretty skeptical view of
> requirements because they often have holes in them. It pays to be a bit
> circumspect.

Doesn't matter. You (a) would have been told that your suspicions are
not
a concern, since the Ariane 4 and 5 have the same flight profile, and
(b)
don't go throwing dumb assertions throughout your code - we're already
running around 80% of max throughput!

> With regard to whether an Eiffel software engineer would have
> picked up the false assumption compared with an Ada SE - possibly, due to the
> fact that they are conditioned by their use of contracting to *think* of as
> many assumptions as possible so they can code them as assertions. This sort of
> conditioning is much less prevalent among Ada developers because most don't
> use contracting (in this disciplined sense). I *know* this is true because I
> work with them. Of course, they may be (and probably are) more disciplined
> in your domain simply because they *have* to be. However, the conditioned
> cultural difference due to disciplined contracting would be an advantage.

Our engineers are taught the same thing in ADARTS, so I don;t think this
is
as big a difference as you think.

I also challenge whether or not you code all of the assertions you can
envision.
Look at your example from earlier. There's absolutely no other
assertions you
could consider? How about the possibility that calling one of the
functions
in the assertion causes NO_OF_KEYS to become non-zero, just for fun?

> For your domain it's a bit of a Catch-22. Contracting would improve the culture
> but you're unable to use it due to hard timing constraints.

Not at all. We have to distinguish between "contracting" and
"assertions." You
can still think in terms of writing strong interfaces, with well
documented
user constraints (ADARTS term), but without coding them. For example,
you may
write your test cases such that pre-conditions, post-conditions, and
invariants
are checked outside the object code. You can also permit more
comprehensive
reviews by documenting them via comments. The point is, you don't have
to use
DBC/Eiffel to get these benefits... they are also contained in
ADARTS/Ada, for
example.

> 
> 
> :However, their
> :explanation as to why this is true is far from convincing (basically,
> :that "Eiffel
> :programmers believe in quality" or some such nonsense).
> 
> No, it's the conditioning that makes the difference. There are a lot of
> Ada software engineers who *are* serious about quality (including you, I expect).
> Using DBC just makes you more effective.

However, the supposed advantage of Eiffel is that this thinking becomes
code.
I don't see the advantage for my domain (although I certainly do for
others).

> 
> :This is why I dislike people with no background in safety-critical
> :flight systems discussing
> :such issues. They believe that "software is software." and apply the
> :expertise in their
> :domain to mine.
> 
> Well, having worked in a range of application areas from HRT to 4GL/database,
> I can say this is both true and false. What I mean is there are some principles
> (eg. how to structure code etc.) that don't change irrespective of whether
> you're developing an embedded system or a GUI-based client application on a PC.
> There are also things that *do* change. In particular, the options available
> to you progressively decrease and the development environment becomes more
> hostile as you move further towards the HRT end of the scale (as you know).
> 
> :> :Again, the code I've seen to date doesn't seem to use them that much.
> :>
> :> If you're looking in Ada code, you're looking in the wrong place because few
> :> Ada developers recognise there are additional benefits from using them in
> :> addition to static typing and the predefined contracts already in Ada
> :> (the conditions under which predefined exceptions - eg. Constraint_Error -
> :> are raised).
> :
> :No - I'm looking at Eiffel code.
> 
> Well, you must be looking in the wrong place. I don't know whether anyone
> has given any pointers yet as to where you can find some. Suggestions?..
> 
> :> Static typing gives you static contract checking. Assertions (predefined and
> :> user-defined give you dynamic contract checking *during development*. What
> :> most Ada software engineers miss out on is the user-defined variety which
> :> bring a non-trivial benefit to reliability and reuse.
> :
> :Not this Ada engineer! I have dynamic assertions all over the place in
> :my
> :tools!
> 
> Terrific!
> 
> :My problem, again, is in the fundamental nature of dynamic assertions
> :for safety-critical
> :embedded systems, which have some unique risks, whether you (a) leave
> :them in after development,
> 
> Not recommended for your application area.
> 
> :or (b) take them out after developmental testing, but
> :before usage.
> 
> In this case, the software should be regression tested.

This requires that _all_ of the testing/analysis be done twice. Putting
aside
the cost and schedule concerns, any such program will have finite time
and other material. I can either do all of this work twice (which
dilutes
my effort 50%), or I can do it once - which might allow me to do testing
that otherwise I wouldn't do.

> 
> :> They are only turned on during development, so what you do is fix the underlying
> :> problem which is usually not difficult to find if you've used them systematically.
> :> Even if you haven't (I was the only one of a team of 5 using them in our recent
> :> development cycle), they still tell you more than you would otherwise be told.
> :
> :I am aware of at least one project developing an embedded missile
> :controller,
> :that did exactly what you describe (in Ada). Here's what happened:
> :
> :1. Their timings changed, which introduced some subtle differences in
> :the
> :relationships between tasks and external interrupts. Some of these
> :subtle
> :differences invalidated their original testing.
> 
> This is why I have specifically said they *shouldn't* be used in threads where
> timing is critical. The fundamental problem is that assertions are executed
> *sequentially* and will necessarily affect timing. I haven't thought of any
> bright ideas on this one..
> 
> This is in contrast to GC which can be executed *in parallel* if implemented
> on a shared memory - multi-processor architecture.
> 
> :2. Their object code changed (obviously), which required reanalysis of
> :their
> :object-code branch coverage.
> 
> If assertions are being implemented in a safe way and you can validate that
> the compiler is doing the right thing, why should this be necessary?

Because structural (path) testing at the object level has been shown to
be
extremely useful in detecting various types of errors - compiler errors
among them. Beizer cites several studies.

> 
> :3. At least one compiler bug was introduced, which was definitely
> :unsettling.
> 
> If you really mean a bug (whether from optimisation or something else), this
> is not the fault of contracting but the compiler.

True, but I have to live in the real world. The families of the people I
kill will not be impressed with the statement "That's a tool problem,
not
a methodology problem." The point is, changing the compiler switches
after
testing is complete is a Bad Thing.

> 
> :What safety-critical system did you develop where you turned off
> :assertions
> :afer development?
> 
> None. But if I did, I would regression test to make sure the compiler didn't
> stuff things up.

Do you run all of your tests, and perform all of your analyses, twice
(once with
SA.ASSERTIONS_ON set, and the other with it cleared)? Ever miss a
schedule date,
overrun a budget, or forego any potential testing as a result?

> 
> :What standard (DO-178?) did you use for certification?
> 
> Which is?..

DO-178 is the FAA standard for critical software. It, along with other
commonly-used certification criteria, would likely take a dim view of
what Eiffel advocates propose with respect to not testing the actual
code.

> 
> :The other prong of this is that, while assertions are keen for catching
> :design problems, I haven't seen much evidence that they catch high-level
> :requirements problems (not surprising, since the code was presumably
> :written
> :to match the requirements).
> 
> If you're talking about A-specs (specs above the level of Software Requirements
> Specs) containing statements like "The Sonar simulation shall simulate
> active detection", such requirements are better linked to a bunch of SRS
> requirements and checked through them.

No, code would usually be written to an SRS. Requirements traceability,
while
useful, only says that you implemented/tested what was written. It
doesn't say
that what was written is correct or complete.

> 
> :In 13 years of developing safety-critical
> :embedded systems, our process tends to handle design problems fairly
> :early.
> :It's those high-level requirements problems where we need the most help.
> 
> Can you give an example? Not sure how high-level you mean.

Recent examples:

  Ariane 5 - incorrect operational profile (Ariane 4 specified instead
of 5)
             See:
http://www.esrin.esa.it/htdocs/tidc/Press/Press96/ariane5rep.html
  F-18     - divide by zero at Mach 1, due to incorrect control law
equation in spec.
  YF-22, Gripen - PIO due to incorrect control law equation in spec.
(PIO is
             a complex lag interaction between the operator and the
system -
             can't wait to see the assertion for this one!)

> :> Yes, timing *is* something to be concerned about when applied to realtime
> :> systems. That's why I suggested not using assertions in the hard realtime
> :> threads of a process. BTW, software designed using DBC may actually run *faster*
> :> than code without it because you get to strip out all the defensive validity
> :> checks. You have already ascertained during development that operations are
> :> called in valid contexts so you don't have to check the context.
> :
> :But almost all of our safety-critical threads are hard realtime threads!
> :That's a HUGE limitation for our systems!
> 
> Agree.
> 
> :What is the process to certify Eiffel compilers as being acceptably
> :mature
> :(code generation-wise) for safety-critical systems? Is all testing
> :performed
> :with assertions on and assertions off in all test cases?
> 
> I am not aware of any use of Eiffel yet for safety-critical systems. What I'm
> trying to get across is its *potential* for these systems. That potential
> would be contingent on a number of things happening:
> 
>   - The addition of a concurrency mechanism.
>   - The addition of realtime libraries.
>   - The addition of low-level libraries.
>   - The addition of a formal certification process for Eiffel compilers.
>   - A realisation in RT community of the advantages of using Eiffel.

Much like saying a brick has the potential to fly... if you strap it to
an airplane :)

Aren't there more fundamental problems than just this? You state that
the assertions can't be executed in a hard real-time thread, so how does
a "realtime" library help?

> 
> :> :Another consequence of using assertions is that you have to develop and
> :> :test the
> :> :assertions.
> :>
> :> Correct. My initial reaction when I started using them was "Gee, I've got to
> :> do this extra work on top of writing the "real" code! However, I found I was
> :> spending about a third of the time integrating compared with my colleagues
> :> which meant I was saving time overall and producing more reliable code to boot.
> :>
> :> :As a result, you need confidence that the benefits of the
> :> :assertions
> :> :outweigh the dilution of your test effort.
> :>
> :> IME, they do.
> :
> :However, it sounds like you're talking about a non-safety-critical
> :system, and
> :certainly not a hard real-time embedded safety-critical systems. In that
> :case,
> :I agree. For tools, simulations, etc. I would use all of the assertions
> :I could.
> 
> Yes, I'm talking about simulators. Our's probably regarded as medium realtime.
> 
> :However, what about the topic of this thread (safety-critical systems)?
> :It sounds
> :like there's a lot of limitations as to using (and inheriting)
> :assertions for
> :this environment.
> 
> In the HRT threads, yes. Elsewhere (not in your case), it is an option.

But not all of my issues relate to HRT, so I still don't see that on
balance it's a good idea.

> :> :Of course, Bertand Meyer's Eiffel website insists that even
> :> :misinterpretation of
> :> :requirements (Ariane V) will be a problem no longer when Eiffel is used!
> :>
> :> Come on. He's not saying that.
> :
> :Read his analysis of Ariane V. He says _exactly_ that, and has defended
> :saying that in multiple newsgroups. A smart person, but not someone
> :who knows my domain particularly well.
> 
> That's probably true.
> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00     ` Alan Brain
@ 1997-07-18  0:00       ` Don Harrison
  1997-07-22  0:00         ` Alan Brain
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-18  0:00 UTC (permalink / raw)



Alan Brain wrote:

:Don Harrison wrote:
:>
:> As an example, in our simulation, we have a vehicles object. This is implemented
:> as an array of records (they should be variant records discriminated
:> on validity, however..). Vehicles are activated and deactivated during the
:> course of a "game" by setting a validity flag. I added preconditions to ensure
:> that other attributes (such as heading) were not queried unless the vehicle was
:> active. These simple checks caught a whole bunch of errors that may otherwise
:> have gone unnoticed. In the absence of such a check, the problem may only
:> have come to our attention if spurious behaviour was observed. 
:
:Your experience parallels my own, even to the problem domain (I used to
:work for STN Atlas Elektronik GmbH of Bremen, Germany makers of fine
:machines-that-go-ping)
:
:The difference is that we _did_ use descriminant records. Something
:along the lines of..

[example and explanation of contracting benefits elided]

I agree the technique you describe is a useful one for enhancing reliability.
In fact we *did* use this form of contracting (for that is what it is) liberally
and found it very useful.  

:I realise you know all this (at least in theory) but this is to confirm
:that it works in practice too. Many errors were caught this way.
:
:Any reason why descriminant records weren't used in you project? 

They weren't used in this specific object only due to the restricted scope of 
the rewriting activity. There was initially a high degree of paranoia 
about reworking functionality that was deemed out-of-scope. However, it was 
clear that the benefits (in terms of increased reliablity and maintainability
and of meeting a tight schedule) meant that reworking some supposedly 
out-of-scope code was worthwhile. Where I considered reliability and timeliness
(resulting from reduced debugging time) was likely to be enhanced rather than 
compromised, I stepped outside our charter and simplified code. Previous 
experience with this simulation helped in this regard.

This strategy paid off in that a reliable foundation was laid down for higher 
level modules to build on. This was important in light of the generally low 
initial domain experience of team members with this simulation (a Hull-Mounted 
Sonar + its Operator Console). By applying assertions to low-level objects, 
correct usage in higher level modules was enforced which enhanced overall 
reliability. A significant number of errors were identified as a result of 
this strategy. 


[Alan, I visited Le Rendezvous where we used to have pizza when we were at C3.
Unfortunately, it's gone glitzy. What a shame! In the 11 years since then 
I still haven't found a Mexicana to match theirs.]


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00         ` Joachim Durchholz
  1997-07-17  0:00           ` Ken Garlington
  1997-07-17  0:00           ` Robert Dewar
@ 1997-07-18  0:00           ` John Nagle
  1997-07-18  0:00             ` Jon S Anthony
  1997-07-18  0:00           ` Jon S Anthony
  3 siblings, 1 reply; 255+ messages in thread
From: John Nagle @ 1997-07-18  0:00 UTC (permalink / raw)



Joachim Durchholz <joachim.durchholz@munich.netsurf.de> writes:
>Steve Furlong wrote:
>> get or free memory. If your process _must_ check ports every 10 ms,
>> you can't be waiting half a second for memory compaction.

>Arrgh! Will that idea nevere go away!!
>The best available GC algorithms don't go away for compacting; they run
>in parallel with the normal program (as a coroutine if you don't want a
>preemptive scheduler).

>> Modern GC presumably can get around that problem,

>That reads "definitely", not "presumably". The algorithms are there.

     If only the Java people would use them.

					John Nagle




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                   ` Stuart Palin
  1997-07-18  0:00                     ` Ian Rae
@ 1997-07-18  0:00                     ` Paul Johnson
  1 sibling, 0 replies; 255+ messages in thread
From: Paul Johnson @ 1997-07-18  0:00 UTC (permalink / raw)



In article <5qkun1$35r@gcsin3.geccs.gecm.com>, stuart.palin@gecm.com says...

(in reply to my argument that Eiffel assertions are propogated up
through the structure)

>I am not at all convinced by this Paul, in our experiences with SPARK,
>where formal specifications are hoisted up through the program structure
>revealing dependencies of lower level routines it is all too easy to end
>up with an unmanageable number of annotations (assertions).

In most Eiffel code this is not a problem because the classes implement
abstractions, and the assertions relate to those abstractions.

However I can certainly believe that in numerical computation with 
subranges (which in practice means anything except bignums), you get
all sorts of messy problems of the sort that Stuart describes.  I 
therefore conceed the point.

Most programmers can simply ignore arithmetic overflow issues.  Safety 
critical people can't.

Paul.

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-15  0:00         ` Ken Garlington
  1997-07-16  0:00           ` Jean-Marc Jezequel
  1997-07-17  0:00           ` Joachim Durchholz
@ 1997-07-18  0:00           ` Don Harrison
  1997-07-18  0:00             ` Ken Garlington
  2 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-18  0:00 UTC (permalink / raw)



Sorry for taking a while to get back to you..

Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> Ken Garlington wrote:
:> 
:> :Don Harrison wrote:
:> :>
:> :> If even this small overhead is unacceptable, you can force static binding
:> :> where necessary by freezing routines.
:> :> Although you forgo the flexibility of
:> :> polymorphism, you can still take advantage of inheritance by virtue of Eiffel
:> :> synonyms - these allow you to declare a routine under different names.
:> :
:> :But I can do this in Ada, as well, so I don't see the benefit.
:> 
:> I'm not saying there is any extra benefit - merely that you don't have to
:> wear the overhead of dynamic binding if you're desperate to maximise efficiency.
:> Tucker mentioned that overhead. I'm saying it isn't an issue.
:
:But you also said that it was required to use that part of Eiffel
:inheritance not
:available in Ada. 

No, you've misunderstood. What I'm saying is:

  1) If you want to forget about using polymorphism in Eiffel, you can force 
     static binding by freezing features. This prevents you from redefining 
     that feature in a descendant.
  2) However, if you want to leave open the possibility of redefining you 
     can call a feature by two names - do_something and frozen_do_something.
     This allows you to use frozen_do_something in all calls (thus forcing
     static binding) and still be able to redefine the feature via the other name.
     (See my previous post for the example of "equal" and "frozen_equal").

Whether or not you can acheive the same thing with tagged types and renaming
I wouldn't have a clue.


:In this statement, you seem to be saying that if I
:want an
:efficient safety-critical system (which I always do), I have to give us
:some of
:that extra inheritance.

Not inheritance but polymorphism.

: Do I need the full Eiffel inheritance model, or
:don't I?

Probably not - don't know.


:> BTW, how do call a procedure under different names in Ada?
:
:Via the "rename" statement.
:
:> 
:> : :Does this "pre-allocated memory pool" mean that you will know exactly
:> :> :what address
:> :> :each object's data will reside at, or merely that you dynamically
:> :> :allocate memory
:> :> :at initialization and do not dynamically allocate after initialization
:> :> :is complete?
:> :>
:> :> The latter. You don't actually need to know *where* objects are allocated,
:> :> merely that there is sufficient memory to allocate them.
:> :
:> :Actually, in my systems, I do need to know where they are allocated, so
:> :that
:> :I can examine them from the hideously crude display in the cockpit
:> :during
:> :troubleshooting.
:> 
:> That *is* hideously crude (and brings back some bad memories). Depending on how
:> crude you mean, maybe a primitive tool could give you a map of where objects get
:> put in memory. If you mean incredibly crude, use non-reference (expanded in
:> Eiffel) types and use a linker-generated memory map.
:
:Both approaches require that the memory address be known before
:execution time,
:however, so I still care where objects are located. I also care for
:other reasons,
:such as memory-mapped I/O, of course.

Yes.


:> :> Maybe general assertions are more common than you imagine. However, I agree
:> :> that range constraints are roughly covered by Ada subtypes. I use them liberally
:> :> for just that purpose.
:> :
:> :Maybe, but again, I would like to see how these complex assertions are
:> :used.
:> 
:> You would use them anywhere that a piece of code makes assumptions. For example,
:> to help avoid the Ariane fiasco, include contracts in the INS(?) that specify
:> Ariane 4 dynamics. Then, in testing, you will get an assertion violation when
:> you apply Ariane 5 dynamics to it.
:
:This is why my blood pressure goes up!

Well, this was naive of me wasn't it? In mentioning the very word "Ariane" 
a thousand assumptions come flooding into some people's minds about what you
are implying. I was implying nothing - just responding to your request for 
an example of a high level assertion. I did not intend to imply any deficiency 
of Ada in this or anything else that you may have assumed.

So, here's a different example. In my key handling object (one of the highest
level in the simulation), there's an operation for interpreting the CLEAR key.
Simplifying a little, pressing this key should reactivate the menu, clear the 
key sequence and clear any menu or sub-menu selection. So, there's a compound
postcondition thus:

      if SA.ASSERTIONS_ON and then (INPUT_STATE /= MENU or else 
        NO_OF_KEYS /= 0 or else MENU_OPTION_SELECTED or else
        SUBMENU_OPTION_SELECTED) then
        raise SA.POSTCONDITION_ERROR;

Note that some of the components are functions. Wrapping them in this way 
is typical practice in Eiffel and enables you to use them elsewhere (eg. in 
if-statements in the code proper) and makes contracting scalable.


:The _Ada_ implementation did generate an assertion violation the very
:first time
:Ariane 5 dynamics were applied to it. Unfortunately, the very first time
:Ariane 5
:dynamics were applied to it was at LANUCH!

Yes. 


:They were not applied earlier, because the contractor assumed that the
:Ariane 5
:dynamics were the same as the Ariane 4, so why spend the money testing
:to the same
:conditions already tested earlier? (They were wrong, of course, but they
:didn't know
:that at the time).

Not a good assumption.


:The other part of the problem was that the _response_ to the assertion
:violation was
:wrong. The designer assumed the assertion would occur due to a hardware
:failure, not
:a software requirements failure, and so the handler shut down the
:"offending" hardware,
:rather than attempting some other action (e.g. replacing the
:out-of-range value with
:a "safe" value)..

Clearly, the assumptions weren't properly thought out. Getting them right 
would have made the difference.


:According to Meyer, et. al. Eiffel programmers would have written the
:handler
:differently, and also they would have known to do the testing
:differently (even though
:the requirements specification said that the tests need not change).

I don't know about you, but I tend to take a pretty skeptical view of 
requirements because they often have holes in them. It pays to be a bit 
circumspect. With regard to whether an Eiffel software engineer would have 
picked up the false assumption compared with an Ada SE - possibly, due to the 
fact that they are conditioned by their use of contracting to *think* of as 
many assumptions as possible so they can code them as assertions. This sort of 
conditioning is much less prevalent among Ada developers because most don't 
use contracting (in this disciplined sense). I *know* this is true because I 
work with them. Of course, they may be (and probably are) more disciplined 
in your domain simply because they *have* to be. However, the conditioned 
cultural difference due to disciplined contracting would be an advantage. 

For your domain it's a bit of a Catch-22. Contracting would improve the culture 
but you're unable to use it due to hard timing constraints.

 
:However, their
:explanation as to why this is true is far from convincing (basically,
:that "Eiffel
:programmers believe in quality" or some such nonsense). 

No, it's the conditioning that makes the difference. There are a lot of 
Ada software engineers who *are* serious about quality (including you, I expect). 
Using DBC just makes you more effective.


:This is why I dislike people with no background in safety-critical
:flight systems discussing
:such issues. They believe that "software is software." and apply the
:expertise in their
:domain to mine. 

Well, having worked in a range of application areas from HRT to 4GL/database, 
I can say this is both true and false. What I mean is there are some principles 
(eg. how to structure code etc.) that don't change irrespective of whether 
you're developing an embedded system or a GUI-based client application on a PC. 
There are also things that *do* change. In particular, the options available 
to you progressively decrease and the development environment becomes more 
hostile as you move further towards the HRT end of the scale (as you know).


:> :Again, the code I've seen to date doesn't seem to use them that much.
:> 
:> If you're looking in Ada code, you're looking in the wrong place because few
:> Ada developers recognise there are additional benefits from using them in
:> addition to static typing and the predefined contracts already in Ada
:> (the conditions under which predefined exceptions - eg. Constraint_Error -
:> are raised).
:
:No - I'm looking at Eiffel code. 

Well, you must be looking in the wrong place. I don't know whether anyone 
has given any pointers yet as to where you can find some. Suggestions?..


:> Static typing gives you static contract checking. Assertions (predefined and
:> user-defined give you dynamic contract checking *during development*. What
:> most Ada software engineers miss out on is the user-defined variety which
:> bring a non-trivial benefit to reliability and reuse.
:
:Not this Ada engineer! I have dynamic assertions all over the place in
:my
:tools!

Terrific!


:My problem, again, is in the fundamental nature of dynamic assertions
:for safety-critical
:embedded systems, which have some unique risks, whether you (a) leave
:them in after development, 

Not recommended for your application area.

:or (b) take them out after developmental testing, but
:before usage.

In this case, the software should be regression tested.


:> They are only turned on during development, so what you do is fix the underlying
:> problem which is usually not difficult to find if you've used them systematically.
:> Even if you haven't (I was the only one of a team of 5 using them in our recent
:> development cycle), they still tell you more than you would otherwise be told.
:
:I am aware of at least one project developing an embedded missile
:controller,
:that did exactly what you describe (in Ada). Here's what happened:
:
:1. Their timings changed, which introduced some subtle differences in
:the
:relationships between tasks and external interrupts. Some of these
:subtle
:differences invalidated their original testing.

This is why I have specifically said they *shouldn't* be used in threads where 
timing is critical. The fundamental problem is that assertions are executed 
*sequentially* and will necessarily affect timing. I haven't thought of any 
bright ideas on this one..

This is in contrast to GC which can be executed *in parallel* if implemented 
on a shared memory - multi-processor architecture. 


:2. Their object code changed (obviously), which required reanalysis of
:their
:object-code branch coverage.

If assertions are being implemented in a safe way and you can validate that 
the compiler is doing the right thing, why should this be necessary?


:3. At least one compiler bug was introduced, which was definitely
:unsettling.

If you really mean a bug (whether from optimisation or something else), this 
is not the fault of contracting but the compiler.


:What safety-critical system did you develop where you turned off
:assertions
:afer development? 

None. But if I did, I would regression test to make sure the compiler didn't
stuff things up.


:What standard (DO-178?) did you use for certification?

Which is?..


:The other prong of this is that, while assertions are keen for catching
:design problems, I haven't seen much evidence that they catch high-level
:requirements problems (not surprising, since the code was presumably
:written
:to match the requirements). 

If you're talking about A-specs (specs above the level of Software Requirements
Specs) containing statements like "The Sonar simulation shall simulate 
active detection", such requirements are better linked to a bunch of SRS 
requirements and checked through them.


:In 13 years of developing safety-critical
:embedded systems, our process tends to handle design problems fairly
:early.
:It's those high-level requirements problems where we need the most help.

Can you give an example? Not sure how high-level you mean.


:> Yes, timing *is* something to be concerned about when applied to realtime
:> systems. That's why I suggested not using assertions in the hard realtime
:> threads of a process. BTW, software designed using DBC may actually run *faster*
:> than code without it because you get to strip out all the defensive validity
:> checks. You have already ascertained during development that operations are
:> called in valid contexts so you don't have to check the context.
:
:But almost all of our safety-critical threads are hard realtime threads!
:That's a HUGE limitation for our systems!

Agree.


:What is the process to certify Eiffel compilers as being acceptably
:mature
:(code generation-wise) for safety-critical systems? Is all testing
:performed
:with assertions on and assertions off in all test cases?

I am not aware of any use of Eiffel yet for safety-critical systems. What I'm
trying to get across is its *potential* for these systems. That potential 
would be contingent on a number of things happening:

  - The addition of a concurrency mechanism.
  - The addition of realtime libraries.
  - The addition of low-level libraries.
  - The addition of a formal certification process for Eiffel compilers.
  - A realisation in RT community of the advantages of using Eiffel.


:> :Another consequence of using assertions is that you have to develop and
:> :test the
:> :assertions.
:> 
:> Correct. My initial reaction when I started using them was "Gee, I've got to
:> do this extra work on top of writing the "real" code! However, I found I was
:> spending about a third of the time integrating compared with my colleagues
:> which meant I was saving time overall and producing more reliable code to boot.
:> 
:> :As a result, you need confidence that the benefits of the
:> :assertions
:> :outweigh the dilution of your test effort.
:> 
:> IME, they do.
:
:However, it sounds like you're talking about a non-safety-critical
:system, and
:certainly not a hard real-time embedded safety-critical systems. In that
:case,
:I agree. For tools, simulations, etc. I would use all of the assertions
:I could.

Yes, I'm talking about simulators. Our's probably regarded as medium realtime.


:However, what about the topic of this thread (safety-critical systems)?
:It sounds
:like there's a lot of limitations as to using (and inheriting)
:assertions for
:this environment.

In the HRT threads, yes. Elsewhere (not in your case), it is an option.


:> :Of course, Bertand Meyer's Eiffel website insists that even
:> :misinterpretation of
:> :requirements (Ariane V) will be a problem no longer when Eiffel is used!
:> 
:> Come on. He's not saying that.
:
:Read his analysis of Ariane V. He says _exactly_ that, and has defended
:saying that in multiple newsgroups. A smart person, but not someone
:who knows my domain particularly well.

That's probably true.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00           ` Jon S Anthony
@ 1997-07-18  0:00             ` Nick Leaton
  1997-07-18  0:00               ` Jon S Anthony
  0 siblings, 1 reply; 255+ messages in thread
From: Nick Leaton @ 1997-07-18  0:00 UTC (permalink / raw)



Jon S Anthony wrote:

... Delete GC comments

> Highly unlikely given the sort of setting Steve seems to have in mind.
> Think of an ECU where the 10ms time limit is the hard limit on the
> evaluation loop and every cycle available in that time limit is used
> up by "real" work.

And this is in a safety critical development? Tell me where so I can
avoid it if possible. If you are so close to the time limit, you have no
margin for error which isn't very safe.

-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00         ` Joachim Durchholz
                             ` (2 preceding siblings ...)
  1997-07-18  0:00           ` John Nagle
@ 1997-07-18  0:00           ` Jon S Anthony
  1997-07-18  0:00             ` Nick Leaton
  3 siblings, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-07-18  0:00 UTC (permalink / raw)



In article <33CBF5DE.D5FB1B6C@munich.netsurf.de> Joachim Durchholz <joachim.durchholz@munich.netsurf.de> writes:

> Steve Furlong wrote:
> > get or free memory. If your process _must_ check ports every 10 ms,
> > you can't be waiting half a second for memory compaction.
> 
> Arrgh! Will that idea nevere go away!!
> The best available GC algorithms don't go away for compacting; they run
> in parallel with the normal program (as a coroutine if you don't want a
> preemptive scheduler).

Well, I'm certainly a GC supporter (as many here know only too well
:-), but there's more to this than a simplistic "yes it can" "no it
can't".

First, compacting may well have nothing to do with it.  What
compacting are you talking about?  The sort that you get for "free" in
a copying collector?  Or do you really mean a compacting MS style
collector?  Even generational variants of the former will likely suck
up _way_ too much memory for the sort of application that Steve is
talking about.  And for the latter, true compaction activity
interwoven with mutator activity is non-trivial.  The techniques would
be closer to incremental or true concurrent collectors.  Now, these
latter are _claimed_ to be sufficient in _some_ real time scenarios.
But, a) this is typically predicated on some sort of HW support for
the GC, and b) even then, the sort of time constraints Steve is
talking about seem implausible given the current evidence.

Given the sort of application Steve seems to be talking about, I don't
think that current GC could guarantee things and besides, it probably
wouldn't buy you that much anyway - it's not likely that the
structures involved in the sort of program indicated would be highly
interwoven, which is when manual deallocation becomes extremely
burdensome and highly error prone (maybe outright impractical).


> That reads "definitely", not "presumably". The algorithms are there.

Highly unlikely given the sort of setting Steve seems to have in mind.
Think of an ECU where the 10ms time limit is the hard limit on the
evaluation loop and every cycle available in that time limit is used
up by "real" work.


/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
       [not found]                 ` <JSA.97Jul17174044@alexandria.organon.com>
@ 1997-07-18  0:00                   ` Nick Leaton
  1997-07-18  0:00                   ` Joachim Durchholz
  1 sibling, 0 replies; 255+ messages in thread
From: Nick Leaton @ 1997-07-18  0:00 UTC (permalink / raw)



Jon S Anthony wrote:
> 
> In article <33CE082E.65FF@calfp.co.uk> Nick Leaton <nickle@calfp.co.uk> writes:
> 
> > Why would you want to place procedural code in an assertion? It is the
> > same as saying you want to have a side effect of a function. If it is
> 
> Unless you are using a pure functional or declarative language, you
> are writing "procedural" code.  Eiffel is about as close to either of
> these as Ada or Pascal or C.  So, if you are writing your assertions
> in Eiffel, you are writing procedural code.
> 
> If you really do want functional code - go use a _functional_ language!

Check the post I was replying too!

Procedure - does something
Function - returns the value of something.

The original post refered to have some critical procedure being placed
in an assertion, and the problem of then diasabling the assertion!


-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-07-18  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  0 siblings, 0 replies; 255+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-07-18  0:00 UTC (permalink / raw)



Paul Johnson <paul.johnson@GECM.COM> writes:
>
>The thing is that in Eiffel the assertions are not just a run-time error
>detection mechanism, they are also a documentation and specification
>mechanism.  The Ada assertion was invisible because it was buried in the
>implementation of the routine that failed.  An equivalent Eiffel routine
>(if it were correct) would have had the assertion in its interface, and
>so on up to the top level of the software package under discussion.  So
>anyone reusing the package would have seen the assertion.  The Inquiry
>specifically commented that the Ada assertion was buried so deeply that
>it was effectively invisible to any review.
>
    Please correct me if I'm wrong. My understanding was that the code
    in question had explicitly turned off range checking on some of
    the parameters in question in the interest of performance. Without
    the range checking (and subsequent raising of Constraint_Error),
    what was left was a fixed point overflow interrupt - which was
    accommodated by turning off the channel and transferring control to
    the other side. Hence there was no "Ada assertion" as such because
    whatever safety features the language has had been disabled. Sort
    of like driving with your seat belt unfastened.

    (This is why I conclude that Eiffel wouldn't have saved the day
    because the developers would have turned off assertions here as
    well. Is the last of my memory fading? Am I entering the
    springtime of my senility? Or am I remembering correctly?)

    MDC

Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
===============================================================================
    "A government that is big enough to give you all you want is big
    enough to take it all away."
        --  Barry Goldwater
===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-07-18  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  0 siblings, 0 replies; 255+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-07-18  0:00 UTC (permalink / raw)



Nick Leaton <nickle@CALFP.CO.UK> writes:
>Separate point. One of the valid objections that has been raised with
>assertions is question of execution time being different with them on
>from when they are off.
>
>From other posters, it seems that with life critical systems (avionics)
>that this is an important consideration. Am I the only one who finds
>this worrying, that systems you have to trust depend on some calculation
>as to how the program is going to run? What happens if a new compiler
>comes out that has a different optimisation technique?
>
    With lots of embedded systems, you're running near the limits of
    processor speed. This is especially true of deep space systems
    where the environment limits you to a very small set of processors
    & memory devices which are of very old design and run *real* slow
    in comparison to what is available today. Hence, you turn off all
    the runtime checks because you simply can't afford them. You
    compensate for this by careful software design and very rigorous
    testing across every condition you can imagine (or until the
    budget runs out or the schedule is shot ;-)

    Typically, when a critical computer such as an engine control or a
    navigation computer reaches the point where you're ready to go to
    flight certification, you freeze the compiler version. (Usually, a
    long time before you go for certification because you're
    verification can't be done against a moving target.) The compiler
    version (and a bunch of other stuff) is frozen for exactly the
    concern you express: "What if something were to change the code
    that is output when we recompile module X?"

    I don't know of any systems that are capable of enabling/disabling
    runtime checks dynamically, so if you compiled the code to perform
    the checks and it ran within its time budget, cool. If you can't
    run with checks enabled, you compile the code that way and it's
    not going to change in flight, so it won't suddenly and
    inexplicably jump up it's CPU utilization.

    With all these sort of systems, you shoot for a highly predictable
    performance behavior and it's not that hard to achieve if your
    execution model is appropriate. So relax - we won't accidentally
    shut down your critical flight control computer by uploading new
    code to it via Internet/Java scripts. :-)

    MDC

Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
===============================================================================
    "A government that is big enough to give you all you want is big
    enough to take it all away."
        --  Barry Goldwater
===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00               ` Robert Dewar
  1997-07-17  0:00                 ` Paul Johnson
@ 1997-07-18  0:00                 ` Don Harrison
  1997-07-20  0:00                 ` Don Harrison
  2 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-18  0:00 UTC (permalink / raw)



Robert Dewar wrote:

:By the way, does Eiffel have fixed-point types? If not, presumably the
:entire code would have been obscured by manual scaling ... And if you
:think you can add fixed-point types by simply defining packages, think
:again 

I think you're mistaken. I don't see any reason why they couldn't be added 
in much the same way as classes INTEGER and REAL. They could even be implemented
by wrapping around Ada fixed-point types. :)

What specifically do you think is the problem? If you post details, we can 
comment.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                 ` Ken Garlington
@ 1997-07-18  0:00                   ` Paul Johnson
  1997-07-18  0:00                     ` Jon S Anthony
  1997-07-18  0:00                     ` Ken Garlington
  0 siblings, 2 replies; 255+ messages in thread
From: Paul Johnson @ 1997-07-18  0:00 UTC (permalink / raw)



In article <33CEB334.44C5@flash.net>, kennieg@flash.net says...
>
>Paul Johnson wrote:

>> However if you call a routine from within a class, there is nothing to
>> say that the assertions have to be maintained.  In fact it would be
>> very restrictive to say that they must be.
>
>OTOH, wouldn't I want the option to see if intra-class dependencies
>cause assertions to be violated? (Actually, in my case, I generally 
>do want this...)

You can always put in "private" assertions, such as "check" clauses
(similar to the classic C "assert" macro), and loop variant and invariant
clauses.

>Certainly, if I wanted to have my Ada exceptions raised only from an
>external caller, it would not be particularly difficult to structure my
>package to do this.

How?  It sounds like you would have to have internal and external
versions of all routines, all suitably redefined in the presence of
inheritance.  This is not a trivial suggestion.

>So, other than maybe writing a little less code, what's
>the significant advantage of this approach? Is it safer to not enforce
>assertions for intra-class dependencies?

Suppose I have an invariant in my class: "foo (a, b) = 0"

This states a relationship between a and b.

Now my class could have one routine which computes both a and b 
simultaniously.  Or it could have one routine which computes a, and
another routine which computes b.  This is purely an internal
implementation decision, so I should be able to chose either.

But if I have in my class the following two lines

   compute_a;
   compute_b;

then under your scheme I will get an exception.  As "compute_a" terminates,
the invariant will be checked, and will fail.  So the public assertion
constrains the private implementation.

(Actually, its even worse.  If I assign to a and then call any
routine before assigning to b then I'll trip the invariant check)

>I still don't see the big advantage from a safety-critical
>perspective...

The Eiffel rules for assertion checking allow the software to be laid out
in the most logical manner, making proper use of functions and procedures.  
This helps the programmers avoid bugs.


>> >Why would I have to duplicate assertions?
>> 
>> Because of the Liskov Substitutability Principle.
>
>To expand: Why do I have to duplicate assertions _in Ada_?

Well, Ada these days has inheritance.  If you want to write correct
software then descendants must inherit their ancestors contracts.
If you want to check and document this then you have to write the
appropriate assertions.


>> In many compilers, if you say "assert: require = (a > b)" then the compiler
>> will observe that the value of "require" is not used thereafter, and
>> remove the statement.
>
>Since this isn't Ada, I couldn't comment.

This discussion started when someone (I assumed it was you, sorry I didn't
check) proposed a type "require" defined as a subrange of Boolean constrained
to be true.  The above statement declares a variable "assert" of type
"require" and initialises it to "(a > b)".  If this expression evaluates to
false then a range exception will be triggered.  Sorry if I've got the
syntax wrong, and sorry that my explanation was wrong as well: I should have 
said "... the value of 'assert' is not used thereafter ...".

Of course there are other ways of writing assertion checks in Ada.

>> The whole point of Eiffel assertions is that in a correct program they
>> have no effect on execution.  Therefore you get exactly the same results
>> whether they are enabled or not.
>
>This would require (a) no changes in timing 

If your software depends upon timing for the correctness of its results
then I would certainly not want to see your software used in safety
critical applications.

I agree that timing variations can cause different results, but why would
they cause incorrect results?  If they don't cause incorrect results then
why are you worried?

>and (b) zero probability
>that the compiler generates incorrect code with a certain combination of
>compiler switches and code. I am skeptical.

What does this have to do with the problem under discussion?  I agree that
this can happen, but why does the ability to enable and disable assertions
cause any new problems?

>> Apart from assertion exceptions, the only way that the execution of an
>> assertion can make a difference is if you call a function with side effects.
>> Eiffel functions are specifically banned from having side effects.
>
>See above.

Functions that might have side effects are fairly easy to detect (they
assign to non-local variables, or call other routines that do so).  This
can be statically checked.

Sometimes a function will cache a result for future use.  I've written
table classes that do this.  Such functions are fairly rare.  When detected
by static checks they can either be inspected carefully or simply banned.

>> Of course, you *can* leave them enabled, but it slows down your code.
>
>It does something else. It requires you to decide what to do if the
>assertion is violated during execution.

Surely the same arguments apply to Ada?  Look at Arianne 5.

>> Some people
>> leave preconditions on in production code as well, if there are no speed
>> problems as a result.

>What do they do if the assertion is violated?

Depends on the application.  Generally they print an error report, dump
stack information to a file, and ask the user to phone the vendor.  Note
that I am not proposing this for real-time embedded applications.  However
there are safety-critical applications which are not real-time.
 
>> >> [Difficulty of getting "short-flat" forms]

>You haven't read my Ada specs!

Are you saying that you write the contract in comments in the spec?  If
so then good for you: its good practice.  The problem is that you have 
now duplicated the information: one copy is in comments, and the other
is in the assertions in the code.  Hence you have doubled the associated
work, and increased the risk of an error.  Eiffel requires that you write
the contract once, and uses the text for both purposes.

I'll agree that all of the benefits of Eiffel assertions are available
in Ada if you put in enough work, but why all this effort to do something
that Eiffel does automatically?  Also if the work becomes too onerous
then it tends to get dropped when schedule and budget pressure is on.
This has been the vice of software engineering ever since the discipline
was invented.  Eiffel makes good practice so cheap, easy and obvious 
that people do it without needing to make a special point of it.

[Stuff about deriving documentation from specs deleted: we seem to be in
broad agreement]

Paul.

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
       [not found]               ` <EDHqKo.K52@world.std.com>
@ 1997-07-18  0:00                 ` Jon S Anthony
  1997-07-19  0:00                   ` Robert A Duff
  0 siblings, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-07-18  0:00 UTC (permalink / raw)



In article <EDHqKo.K52@world.std.com> bobduff@world.std.com (Robert A Duff) writes:

> >> In article <JSA.97Jul13164937@alexandria.organon.com>, 
> >> jsa@alexandria.organon.com says...
> >> 
> >> >    type Require is boolean range True..True;
> >> >...
> >> >
> >> >    Assert : Require := Complex_Precondition(X);
> 
> This isn't quite right, because RM-11.6 allows the check to be
> eliminated.

Bob, could you clarify this?  I just had a look at 11.6 and I'm not
clear on how this works.  For example given the above it would clearly
be the case that you would also have:

...
exception
    when E : Constraint_Error =>
        Do_Something(....)...

in order to catch and do something in case the CE is raised.  How
could the implementation know that this would not "have some effect on
the external interactions of the program"????  I don't see how that is
possible (but then there's the old saying, "if it happens, it must be
possible"...)


> >> 4: You had better be pretty sure that the compiler is not going to
> >> optimise your checks into oblivion during debugging, and conversely
> >> you need a way to turn them off for production code.
> >
> >???  As long as it is _legal_ (does not change the _meaning_ of the
> >code) this would be a _good_ thing!  It amounts to verification at
> >_compile_ time.
> 
> An optimizer can change the *behavior* of a program without changing its
> *semantics*.

I know what you mean here, but a more accurate description would be
that an optimizer can change the behavior as long as that behavior is
not part of the defined semantics.

> This is true in all programming languages, including Ada.  Mostly,
> you're right -- if the optimizer can prove an assertion at compile
> time (and the optimizer is not buggy) then that's good.  But the
> 11.6 cases I mentioned above are troublesome.  In Ada, I prefer to
> use an Assert routine, or a pragma Assert (if supported by the
> compiler).  End users care about the *behavior*.

Actually, if they really did care about behavior that was _not_ part
of the defined semantics, wouldn't that really be a case of an
"erroneous" or possibly "bounded error" program????


/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00             ` Nick Leaton
@ 1997-07-18  0:00               ` Jon S Anthony
  0 siblings, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-18  0:00 UTC (permalink / raw)



In article <33CF2193.18B0@calfp.co.uk> Nick Leaton <nickle@calfp.co.uk> writes:

> Jon S Anthony wrote:
> 
> ... Delete GC comments
> 
> > Highly unlikely given the sort of setting Steve seems to have in mind.
> > Think of an ECU where the 10ms time limit is the hard limit on the
> > evaluation loop and every cycle available in that time limit is used
> > up by "real" work.
> 
> And this is in a safety critical development? Tell me where so I can
> avoid it if possible. If you are so close to the time limit, you have no
> margin for error which isn't very safe.

I was speaking somewhat more generally - realtime applications (which
may or may not be safety critical).  The most typical example of this
sort of thing that most everyone reading this NG probably uses
everyday is your car.  Turn on the ignition and, voila', you are using
such an application.  It is also worth noting that a) it is
_stunningly_ robust compared to the vast majority of software and b)
may well be written in lowly assembler...

But, that doesn't mean the same sort of constraint isn't there for
safety critical applications and there for a _very important reason_.
That hard 10ms time limit may be there in order to _ensure_ enough
_spare_ cycles are _always_ available for a non-nominal event.  That
is, you are _guaranteeing_ an appropriate margin of error.  Given that
you apparently think that would somehow be a bad thing, all I can say
is I'm glad you are not working on such applications (I infer that you
are not by the mere suggestion you make).

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                   ` Stuart Palin
@ 1997-07-18  0:00                     ` Ian Rae
  1997-07-18  0:00                     ` Paul Johnson
  1 sibling, 0 replies; 255+ messages in thread
From: Ian Rae @ 1997-07-18  0:00 UTC (permalink / raw)



Stuart Palin wrote:
> 
> I am not at all convinced by this Paul, in our experiences with SPARK,
> where formal specifications are hoisted up through the program structure
> revealing dependencies of lower level routines it is all too easy to end
> up with an unmanageable number of annotations (assertions).  This means
> that trying to find a possible risk like the Ariane remains impractical
> using this technique since it is like looking for the proverbial needle
> in a haystack.

Good point; assertions tend to be used for both interface and
implementation
assumptions.

However, assertions have the nice property of playing two roles: (a) as
documentation in the source code, and (b) as run-time checks.  The
needle
that can't be seen will be identified when it jams up the baler machine.
This, of course, assumes you're making very small bales (ie. doing very 
rigorous testing).

--Ian Rae
Senior Systems Developer
Nortel IDEAS CTI Group




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                 ` Paul Johnson
  1997-07-17  0:00                   ` Jon S Anthony
  1997-07-17  0:00                   ` Stuart Palin
@ 1997-07-18  0:00                   ` Joachim Durchholz
  2 siblings, 0 replies; 255+ messages in thread
From: Joachim Durchholz @ 1997-07-18  0:00 UTC (permalink / raw)



Paul Johnson wrote:
> Where this argument falls down, I'm afraid, is that the package did
> not
> receive its data from another software package, but from a hardware
> sensor.  At this point the whole idea breaks down.  A pity.

Not really. Just wrap the sensor in a class that has as its main feature
a routine read_out that returns the sensor's value. The postcondition of
read_oud should include a condition on the range of possible values.

If the sensor is changed to give a larger range of possible values,
you'll immediately see that the postcondition no longer holds, and
correct the software wherever read_out is called.

This doesn't make totally sure that the error would have been prevented,
but it wouldn't have happened in this way (and that's the best we can
hope for anyway).
Besides, we haven't seen what glitches are likely to happen in Eiffel.
As Don said, the Ariane-5 paper is more marketing than technical.

> >By the way, does Eiffel have fixed-point types? If not, presumably
> the
> >entire code would have been obscured by manual scaling ...
> 
> No, it does not have fixed point types.  And I agree that they cannot
> easily be added by library classes.

That doesn't make much of a difference. The routines have to be
implemented, wether in the compiler or as a library.

And, yes, I'd definitely like to see them in Eiffel. The heritage of the
compile-to-C strategy is showing here...

Regards,
Joachim
-- 
Please don't send unsolicited ads.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00                   ` Paul Johnson
@ 1997-07-18  0:00                     ` Jon S Anthony
  1997-07-18  0:00                     ` Ken Garlington
  1 sibling, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-18  0:00 UTC (permalink / raw)



In article <5qnab3$ft$3@miranda.gmrc.gecm.com> paul.johnson@gecm.com (Paul Johnson) writes:

>>> In many compilers, if you say "assert: require = (a > b)" then the compiler
>>> will observe that the value of "require" is not used thereafter, and
>>> remove the statement.
>>
> >Since this isn't Ada, I couldn't comment.
>
> This discussion started when someone (I assumed it was you, sorry I
> didn't check) proposed a type "require" defined as a subrange of
> Boolean constrained to be true.  The above statement declares a
> variable "assert" of type "require" and initialises it to "(a > b)".
> If this expression evaluates to false then a range exception will be
> triggered.  Sorry if I've got the syntax wrong, and sorry that my
> explanation was wrong as well: I should have said "... the value of
> 'assert' is not used thereafter ...".

Actually, that would be myself who posted that (well known) idiom.
Please note that any compiler that did what you suggest without static
versions of a and b would be buggy.  If a and b are computed or passed
in or whatever, the only way that the compiler could blow off the code
would be if it did complete inter-procedural analysis to ensure that
no side effects anywhere could _possibly_ occur in the computation of
a and b.  Of course, if it could do that and still infer what the
assert would be, then of course it would be free to insert a
Constraint_Error in place of the code (if it was determinted to be
false) or simply remove the code (if it was determined to be true).

But in general, your scenario is either fantasy or a bug in the
compiler.


> Functions that might have side effects are fairly easy to detect (they
> assign to non-local variables, or call other routines that do so).  This
> can be statically checked.

Yes, this is "possible", but in the general case, basically
impractical.  The call graph could be extremely large and complicated
- especially in a dispatching environment.  Even worse - you can add
to the call graph in an inheritance based extension without going back
and recompiling everything that _might_ end up calling your new
side-effect inducing function.  That's actually part of the point of
such OO style extension.  In fact, you might not even be _able_ to go
back and recompile everything even if you decided to take that stance.
Any library code that a client might extend, for which there is no
available source will be impossible in principle to fix up in this
way.

In short, this is easier said than done and your comment evinces a
rather naive view of the matter.  In Ada you can "tag" such a function
as having no side effects by placing it in a "Pure" unit.  But even in
this much more restricted setting it is hard to give absolute
guarantees.


> >It does something else. It requires you to decide what to do if the
> >assertion is violated during execution.
> 
> Surely the same arguments apply to Ada?  Look at Arianne 5.

This is completely irrelevant to the Ariane 5 case.  I'm not sure why
people can't seem to twig this fact.


/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-07-18  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  1997-07-22  0:00 ` Karel Th�nissen
  0 siblings, 1 reply; 255+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-07-18  0:00 UTC (permalink / raw)



Karel Thvnissen <thoenissen@HELLO.NL> writes:
>
>Richie's proposal has a nice property: if we include assertions during
>testing, then if the additional coding affects the timing in an unwanted
>way, then the timing assertion will fail and the problem is revealed. It
>should be clear that in that case the system cannot be tested with
>assertions switched on, and no logical assumptions as described by the
>other assertions can be tested, but at least we know it, and we shall
>have no suprises of unexplanable difference between testing (with
>assertions) and production (without assertions).
>
    It's a nice idea which, unfortunately can't be done. It's often
    not well understood by those who are mostly used to some version
    of workstation or pc based development why you can't test the code
    with compiler option X then recompile you're code with options A,
    B and C and pass it on as "production" software.

    You might do this for some form of "informal" testing - maybe what
    we took to calling "smoke testing". (Since all electronics works
    on the principle of smoke - if you let the smoke out, it stops
    working - the first test is to power it up and see if any smoke
    comes out.) Under those conditions, you could compile any way you
    like, find your problems, fix them and recompile for the "real"
    tests.

    Once you start any sort of formal verification for a safety
    critical system you cannot change any of the bits in the program
    image without having to reverify the image. How much
    reverification you do depends on lots of factors, but it's always
    very expensive and you don't do it lightly.

    One other thing you want to consider is this: If the code *can*
    run with runtime checks enabled, then you probably don't want to
    turn it off for "production" anyway. What do you gain? The only
    reason for turning it off is because it *can't* run with the
    checks on.

    MDC

Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
===============================================================================
    "A government that is big enough to give you all you want is big
    enough to take it all away."
        --  Barry Goldwater
===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00             ` Robert Dewar
@ 1997-07-18  0:00               ` Jon S Anthony
  1997-07-19  0:00                 ` Robert A Duff
  1997-07-21  0:00               ` Don Harrison
  1 sibling, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-07-18  0:00 UTC (permalink / raw)



In article <dewar.869181695@merv> dewar@merv.cs.nyu.edu (Robert Dewar) writes:

> As for the "infuriating" Ada 83 visibility "problem". I always found this
> odd. I understand that people do not like to use "use" because, especially
> with poor tools, they want to be easily able to tell where somethintg
> comes from, but I never understood why this perfectly understandable
> reasoning does not apply to operators (personally I prefer to use "use"
> most of the time anyway).

I quite agree.  What I found odd (at best) about the "use type" thing
in Ada95 was that it doesn't really "use type" - you only get the
operators - a kind of "half-use type".  IMO, this gives you the worst
of both worlds.  If it had really given you all the operations on a
type (not just those using operator syntax) it would have been a
pretty nice idea for those cases where you have more than one such
type in a package.  As it is, I find that "use" is still the clearest
thing to do...

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00               ` Jon S Anthony
@ 1997-07-19  0:00                 ` Robert A Duff
  1997-07-21  0:00                   ` W. Wesley Groleau x4923
  0 siblings, 1 reply; 255+ messages in thread
From: Robert A Duff @ 1997-07-19  0:00 UTC (permalink / raw)



In article <JSA.97Jul18144029@alexandria.organon.com>,
Jon S Anthony <jsa@alexandria.organon.com> wrote:
>I quite agree.  What I found odd (at best) about the "use type" thing
>in Ada95 was that it doesn't really "use type" - you only get the
>operators - a kind of "half-use type".

What *I* find odd is that in something like:

    while X /= null loop
        ...
        X := X.Next;
    end loop;

I can see "null" and ":=" without any use_clause, but I can't see "/=".
And if I don't like use_clauses, the way to get visibility on "/=" is to
rename "="!  (Or else to use the intolerably horrible Package_Name."/=".)
(Actually, I'm not use_clause-phobic.)

By the way, "use type" was a compromise.  The language designers
originally wanted to make primitive operators directly visible always.
But that would have been slightly upward incompatible.  So we settled on
"use type".

>...  As it is, I find that "use" is still the clearest
>thing to do...

I have mixed feelings.  But I do think it's unfortunate that both
opinions exist, because it harms reusability -- you tend to choose
different names for things in a package, depending on whether you expect
clients to use use.

Another pet peeve: In order to use Some_Package, you say "with
Some_Package;".

- Bob




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00                 ` Jon S Anthony
@ 1997-07-19  0:00                   ` Robert A Duff
  1997-07-20  0:00                     ` Tucker Taft
  0 siblings, 1 reply; 255+ messages in thread
From: Robert A Duff @ 1997-07-19  0:00 UTC (permalink / raw)



In article <JSA.97Jul18151414@alexandria.organon.com>,
Jon S Anthony <jsa@alexandria.organon.com> wrote:
>In article <EDHqKo.K52@world.std.com> bobduff@world.std.com (Robert A Duff) writes:
>
>> >> In article <JSA.97Jul13164937@alexandria.organon.com>, 
>> >> jsa@alexandria.organon.com says...
>> >> 
>> >> >    type Require is boolean range True..True;
>> >> >...
>> >> >
>> >> >    Assert : Require := Complex_Precondition(X);
>> 
>> This isn't quite right, because RM-11.6 allows the check to be
>> eliminated.
>
>Bob, could you clarify this?

Suppose Complex_Precondition(X) returns False.  Normally, you would
expect a range check on the assignment, and that would raise C_E.
However, 11.6(5) says the implementation does *not* have to raise C_E,
since *in the absence of raising it*, the result has no external effect.
I'm presuming there are no further references to Assert.  If
Complex_Precondition has externally-visible side-effects, then they must
happen.  If it doesn't (and the compiler can prove it), then the entire
call can also be eliminated.

Another example:

    X: Integer := 999;
    Y: Integer range 1..10 := X;

If there are no further references to Y (or there are, but they in turn
have no external effect), C_E need not be raised.  This is true whether
or not there is a handler for C_E (or others) somewhere (which of course
the compiler doesn't know, since it might be further up the call stack
-- that is, the permission would be useless if the presence of a handler
had something to do with it).

Of course, in order to take advantage of the permission, the compiler
has to prove the absence of external effect.  If Y is a local variable,
that's easy.

I've heard some compiler writers say they would never consider taking
advantage of 11.6, since it would confuse programmers.  I've heard other
compiler writers say that without 11.6, performance would stink.  I also
believe that compilers aren't super clever about taking advantage of
11.6 -- I believe that, because I've seen many ACVC tests that would
fail if the compiler was smarter.  Such ACVC tests are wrong, of course,
but they only get fixed if compiler writers complain.  (You can imagine
why such tests exist -- they are checking that C_E is raised in all the
zillion cases it should be, and it's easy to write a test where the
*only* external effect of the C_E is in the exception handler.  This
isn't the kind of code that occurs a lot in *real* programs.)

The basic idea is that you shouldn't write code that depends on getting
C_E for a failed run-time check (which the "Assert: Require..." example
does).  You can, however, depend on the fact that if a given value is
checked, you can't end up using a junk value in an externally visible
way.  E.g., in the above example, if we add a "Put(Y)", it cannot print
out "999" -- it must raise C_E before that.  In the "Assert: Require"
example, if you print out the value of Assert, then the check will not
be eliminated (but that kind of defeats the purpose of that little
trick).

Note that the permissions apply only to predefined checks.  If you write
an explicit "raise Constraint_Error;" or "raise My_Favorite_Error;",
then the permission does not apply.

>...  I just had a look at 11.6 and I'm not
>clear on how this works.  For example given the above it would clearly
>be the case that you would also have:
                      ^^^^^ could?
>
>...
>exception
>    when E : Constraint_Error =>
>        Do_Something(....)...

You *could* have such a handler, but normally you wouldn't -- you would
just let the program crash, and use debugging tools (and/or your brain)
to figure out why.  After all, you wrote the assertion because you
thought it was true.

>in order to catch and do something in case the CE is raised.  How
>could the implementation know that this would not "have some effect on
>the external interactions of the program"????

I think you're missing the phrase "in the absence of raising it" in the
RM.

>I know what you mean here, but a more accurate description would be
>that an optimizer can change the behavior as long as that behavior is
>not part of the defined semantics.

Yeah, maybe.  My point is just that the semantics (defined in the RM)
defines a *set* of possible behaviors, and the compiler's job is to make
sure that the actual behavior belongs to that set.  If you recompile
with optimization on, or if you simply run the same binary again, you
might get a different behavior.

>>...  End users care about the *behavior*.
>
>Actually, if they really did care about behavior that was _not_ part
>of the defined semantics, wouldn't that really be a case of an
>"erroneous" or possibly "bounded error" program????

Not sure what you mean here.  I'm talking about "end users" -- they
don't normally care one whit what the programming language semantics
are, nor even what programming language was used -- they just want the
program to behave properly.  And they often want the program to be
written in such a way that it always gets the same answer for the same
input.

- Bob




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00           ` Joachim Durchholz
@ 1997-07-19  0:00             ` Ken Garlington
  1997-07-21  0:00             ` Robert S. White
  1 sibling, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-19  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:
> 
> Ken Garlington wrote:
> > > You would use them anywhere that a piece of code makes assumptions.
> > For example,
> > > to help avoid the Ariane fiasco, include contracts in the INS(?)
> > that specify
> > > Ariane 4 dynamics. Then, in testing, you will get an assertion
> > violation when
> > > you apply Ariane 5 dynamics to it.
> >
> > This is why my blood pressure goes up!
> >
> > The _Ada_ implementation did generate an assertion violation the very
> > first time
> > Ariane 5 dynamics were applied to it. Unfortunately, the very first
> > time
> > Ariane 5
> > dynamics were applied to it was at LANUCH!
> >
> > They were not applied earlier, because the contractor assumed that the
> > Ariane 5
> > dynamics were the same as the Ariane 4, so why spend the money testing
> > to the same
> > conditions already tested earlier? (They were wrong, of course, but
> > they
> > didn't know
> > that at the time).
> 
> <Sigh> that misunderstanding again. The issue in the Ariane-5 paper by
> Meyer and Jezequel isn't that the preconditions per se would have
> changed anything. 

Actually, they base the claim on three possibilities, although they
immediately withdraw one (assertion performance during execution).
In addition to the documentation benefits, they state:

"Assertions (preconditions and postconditions in particular) can be
automatically turned on during testing, through a simple compiler
option.
The error might have been caught then."

There are several flaws with this statement, which I have addressed
previously. However, since you have agreed that this would not
have changed anything, I'll skip the analysis of this point.

> The issue is that the preconditions would have been an
> integral part of the routine's signature, and thus not likely to have
> been overlooked by the team that ported the Ariane-4 code to Ariane-5.

There are several flaws in this statement. Since I have addressed them
before in detail, I will summarize them now.

1. There is no evidence that the right precondition (which is not a
simple
   precondition) would have been inserted in the code even using DBC.
   (There is not necessarily a simple correlation between the flight
   profile and the HZ variable in question.)

2. There is no evidence that the reviewer would have had access to the
   Ariane 5 flight profile data necessary to detect the precondition
   violation. (The final report notes that the data was withheld
intentionally,
   with concurrence at several levels. Without this data, the reviewer
   would have been assured that the problem could not occur.)

3. There is no evidence that, if inserted, it would have been reviewed
   by a system engineer, or someone else with the ability to correlate
   the flight profile with the HZ range. (The final report implies that
the
   system specification or a "justification document" might be a more
logical
   place, and that a special team be generated to review these
documents.)

4. There is no evidence that, if inserted, the precondition violation
   would have been manually detected amongst the sea of other
preconditions
   that would have to be manually checked. (The final report makes note
   of the complexity of the system and the difficulty of such analyses,
   and recommends several other items, such as realistic testing, to
   compensate for this difficulty.)

> As it were, the preconditions were buried in some obscure part of the
> documentation, and management didn't reread everything when they reused
> the code (together with its hardware).
> 
> The paper may not be very clear in this respect (I got Meyer's view on
> the topic from his book, not from the paper), or people might
> misinterpret what it's saying.

I don't misinterpret it at all. I merely note that, _in this case_,
there
is no evidence it would have changed anything.

> > According to Meyer, et. al. Eiffel programmers would have written the
> > handler
> > differently, and also they would have known to do the testing
> > differently (even though
> > the requirements specification said that the tests need not change).
> 
> No. They would have written the handler the same way, and documented the
> precondition with the routine where it belongs, not in some obscure spec
> sheets that are shelved away.

Interesting, because the final report notes quite explicitly that the
handler was also a source of the error:

"Although the source of the Operand Error has been identified, this in
itself did not cause the mission to fail. The specification of the
exception-handling mechanism also contributed to the failure."

Thus, if _any_ of the four points above apply, then the results would
have been the same.

Meyer's paper makes no mention of the exception handling approach
defined for DBC; thank you for clarifying this.


> 
> > However, their
> > explanation as to why this is true is far from convincing (basically,
> > that "Eiffel
> > programmers believe in quality" or some such nonsense).
> 
> Well, believing in quality is far from nonsense. And assertions do
> certainly promote a certain style of quality-mindedness.
> It is similar to declaring types for routine parameters. Early C didn't
> have them, current C compilers have them. And besides catching lousy
> errors, the need to declare parameter types makes the programmers
> *think* about what's the right type for a parameter, instead of just
> writing it down. A similar mechanism is at work with assertions and
> Eiffel programmers.

The "nonsense" is that Eiffel programmers have a corner on such
thinking.
Meyer's paper states that "The ESA's software people knew what they were
doing and applied widely accepted industry practices" (the latter
half of this statement is contradicted by the final report), but then
goes on to say "Any team worth its salt would have checked
systematically
that every call satisfies the precondition." Such a statement is
hopelessly naive, as noted above: there are several factors that would
have worked to defeat the best-intentioned review team. None of these
are addressed in the paper (or afterwards).

> 
> > They believe that "software is software." and apply the
> > expertise in their
> > domain to mine.
> 
> Well, their finding may have been badly presented, but I think the
> "software is software" approach is valid. Of course there are
> differences between various levels of safety requirements,

An internally contradictory statement. Can you define these differences,
and explain why they are not a potential factor for this subject?

> but some
> basic themes apply all the same - like static typing, or the need to
> choose meaningful names, etc. Meyer believes that assertions should be
> considered one of these basic themes, and that assertions might have
> prevented the Ariane-5 crash, for the reasons given above. (And I'm very
> much with him, though I'm not informed enough about the Ariane-5 crash
> to decide wether it is a particularly good example of the issue.)

I think you've put your finger on it. People who are Meyer fans, but
not particularly well informed on the Ariane 5 issue, believe Meyer.
People with experience in these kinds of safety-critical systems do
not, at least from what I can tell. Furthermore, there is no
evidence that the paper was even reviewed by someone on the Ariane 5
team, or even someone with a background in such systems, prior to
its publication. I always thought peer review was an essential part of
any scholarly paper.

Note that your statement is wrong, by the way. I could forgive Meyer
to some extent if he had said that assertions "might" have
prevented the Ariane-5 crash. He goes much further: He states that
they "probably" would have avoided the crash. Such a statement carries
with it a much stronger proof requirement, which he fails to provide.

> 
> > I am aware of at least one project developing an embedded missile
> > controller,
> > that did exactly what you describe (in Ada). Here's what happened:
> >
> > 1. Their timings changed, which introduced some subtle differences in
> > the
> > relationships between tasks and external interrupts. Some of these
> > subtle
> > differences invalidated their original testing.
> 
> Timing on that basis is the one thing that Eiffel isn't built for.
> Adding a new class might not change subtle timings, it might totally
> alter the microscopic behaviour of the program. For example,
> non-polymorphic routine calls that could be statically bound by the
> compiler might become polymorphic and required a dynamic dispatch.
> Fine-tuning code so that certain routines are guaranteed to take at
> least x ms and at most y ms sounds to me like a very difficult and
> fragile thing to achieve in Eiffel.

It is a difficult and fragile thing in any language, and best avoided.
More to the point, it is important in testing to look for such
fragile dependencies (race conditions & deadlock in particular). This
testing cannot be done on code with significantly different timing
properties
than the production system.

> 
> > 3. At least one compiler bug was introduced, which was definitely
> > unsettling.
> 
> That's a problem of compiler quality. Eiffel doesn't guarantee perfect
> compilers, but assertions should make bugs less likely.

I presume you mean assertions in the compiler, since obviously the
assertions can't be relied upon to detect errors in the application
at this point. Is there evidence that Eiffel compilers use assertions
extensive internally? Is there evidence that, as a result, they have
far fewer bugs than other compilers? (These aren't idle questions;
if this is the case, this is actually a valid argument for the use of
Eiffel in safety-critical systems that hasn't been offered to date.)


> 
> > The other prong of this is that, while assertions are keen for
> > catching
> > design problems, I haven't seen much evidence that they catch
> > high-level
> > requirements problems (not surprising, since the code was presumably
> > written
> > to match the requirements). In 13 years of developing safety-critical
> > embedded systems, our process tends to handle design problems fairly
> > early.
> > It's those high-level requirements problems where we need the most
> > help.
> 
> Eiffel is the only language that I know that can scale up to formalizing
> high-level requirements. The technique is easy: write a few abstract
> ("deferred") classes that aren't much more than a set of routine
> signatures and assertions.
> One can even implement such a system: Just take the design classes as
> ancestors for your implementation classes. Descendants must keep the
> assertions, so your code is guaranteed to match the specs (in a way -
> assertions aren't statically checked).

I am skeptical that Eiffel is a good language for SRSs. Is there any
evidence that it has been used this way? Are there issues about
the notation being easy to understand by non-programmers?

> 
> > But almost all of our safety-critical threads are hard realtime
> > threads!
> > That's a HUGE limitation for our systems!
> 
> Well, if you don't have confidence in the compiler, there isn't much you
> can do to remove assertions (or run-time range checking, which are a
> limited form of assertions).
> But in this domain there's no difference between Eiffel and Ada - the
> problem's the same, and there is no satisfactory solution available.

Exactly. Again, I think you agree with me that the non-documentation
aspects of Eiffel assertions can be discounted with respect to the
Ariane 5 -- killing two of three of Meyer's arguments. Now, all you
have to do is agree with any one of my four points on documentation,
and we can put this argument to bed :)

I've noticed several times that Eiffel advocates try to make this
a langauge debate betwen Ada and Eiffel. I could care less. I've made
the same points about Ada that I make about Eiffel.


> 
> BTW I'm somewhat curious how these subtle timing differences come to
> have practical consequences. I'm not a hard real-time engineer, so I'd
> expect it doesn't matter if a routine runs faster than expected. How
> come that your experience is obviously different?
> 
> > What is the process to certify Eiffel compilers as being acceptably
> > mature
> > (code generation-wise) for safety-critical systems? Is all testing
> > performed
> > with assertions on and assertions off in all test cases?
> 
> There isn't even a testbed available - probably because nobody earnestly
> demanded it yet.

This seems odd. If Eiffel compilers use assertions, then why wouldn't
the compielr development team, which presumably is "worth its salt,"
establish the high level of quality you assert is the province of
all Eiffel programmers? Why would someone need to "demand" a means to
measure and improve the quality of the toolset?

> 
> > However, what about the topic of this thread (safety-critical
> > systems)?
> > It sounds
> > like there's a lot of limitations as to using (and inheriting)
> > assertions for
> > this environment.
> 
> I think OO in general is difficult to apply here. 

I'm not convinced of this, BTW; I have seen at least object-based
safety-critical real-time systems operate quite nicely. I have also
seen some features of OO not found in object-based designs (e.g.
full polymorphism) used on mission-critical real-time systems, and
I expect that we will use at least some of this in our future
safety-critical systems.

> You obviously need
> tight control on the code generated, to control the timings. A good
> Eiffel compiler will do a global analysis of the system and apply
> inter-routine optimizations. This makes the type of control you desire
> difficult, and I'm not sure wether the better reliability is worth the
> price.

Ada compilers do extensive inter-routine optimizations in our
safety-critical systems. Again, you misunderstand: it's not that the
object code is complex; it is that the object code tested needs to
be the object code delivered.

> 
> > > :Of course, Bertand Meyer's Eiffel website insists that even
> > > :misinterpretation of
> > > :requirements (Ariane V) will be a problem no longer when Eiffel is
> > used!
> > >
> > > Come on. He's not saying that.
> >
> > Read his analysis of Ariane V. He says _exactly_ that, and has
> > defended
> > saying that in multiple newsgroups. A smart person, but not someone
> > who knows my domain particularly well.
> 
> The Ariane-5 crash wasn't a requirements misinterpretation. It was
> overlooking a part of the requirements.

To quote directly from the final report:

"it is even more important to note that it was jointly agreed not to
include the Ariane 5 trajectory data in the SRI requirements and
specification."

I know that Meyer's report makes no note of this fact (it would
weaken his argument considerably if he did!). This is why you need
to read the final report for yourself and compare it critically to
Meyer's interpretation, as I did. Even without a background in this
area, you should see some contradictions.

Meyer, in fact, says: "The requirement that the horizontal bias should
fit on 16 bits was in fact stated in an obscure part of a document.",
but the final report says something a little different: "...three of
the variables were left unprotected. No reference to justification of
this decision was found directly in the source code. Given the large
amount of documentation associated with any industrial application,
the assumption, although agreed, was essentially obscured, though not
deliberately, from any external review." This quote refers to the
deliberate decision by the Ariane 4 designers to _not_ state this
requirement (more importantly, not to _handle_ the case in the code
in the right manner) which, ultimately, caused the failure. How Meyer
got his statement from this, I have no idea.

Don't take my word for it (or Meyer's!): read the report at:

http://www.esrin.esa.it/htdocs/tidc/Press/Press96/ariane5rep.html

> 
> Regards,
> Joachim
> --
> Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00               ` Robert Dewar
  1997-07-17  0:00                 ` Paul Johnson
  1997-07-18  0:00                 ` Don Harrison
@ 1997-07-20  0:00                 ` Don Harrison
  2 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-20  0:00 UTC (permalink / raw)



Robert Dewar wrote:

:In fact the assertion *was* present in the Ada code, in the form of
:a language specified check. 

Correct. This check (for a constraint_error) is a predefined assertion.

:The claim that somehow the programmer would
:have noticed the assertion in Eiffel, while missing it in Ada, is entirely
:bogus in my view.

In the absence of software engineering (as was the case here where testing 
meant launching), I think you're right. The full value of Design by Contract 
is best realised when accompanied by more traditional software engineering 
practice. The two then complement each other - one doesn't obviate the other.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-21  0:00             ` Robert S. White
@ 1997-07-20  0:00               ` nabbasi
  1997-07-21  0:00                 ` W. Wesley Groleau x4923
  0 siblings, 1 reply; 255+ messages in thread
From: nabbasi @ 1997-07-20  0:00 UTC (permalink / raw)



>
>In article <33CD578D.562CC6A4@munich.netsurf.de>, 
>joachim.durchholz@munich.netsurf.de says...
>>
>
>>As it were, the preconditions were buried in some obscure part of the
>>documentation, and management didn't reread everything when they reused
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>the code (together with its hardware).
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

this is so funny. since when management "read" code and "use" code any way? 
if "management" is anything I remember, most have no clue what code is. it
is the responsibility of the programmer to do this, management is there just
to sign the final paperwork :)

now back to the main topic...

Nasser




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00             ` Robert Dewar
@ 1997-07-20  0:00               ` Joachim Durchholz
  1997-07-24  0:00                 ` Joe Buck
  1997-07-24  0:00                 ` Paul M Gover
  1997-07-21  0:00               ` Don Harrison
  1 sibling, 2 replies; 255+ messages in thread
From: Joachim Durchholz @ 1997-07-20  0:00 UTC (permalink / raw)



Robert Dewar wrote:
> The idea that REMOVING the evaluation of boolean expressions
> completely
> is semantically neutral is also completely bogus.

That's a bit strong.

> Such removal can
> affect
> Icache locality of the code that is left, again affecting timing,

OK. Is an issue for real-time software where code timing is important.
I'm somewhat astonished that such code is still written (the last time I
saw this done was on a C64), but then I'm not in the hard RT field.

> and
> can
> also result in code being at different locations, resulting in
> differences
> of behavior with unbounded consequences.

Now *that* sounds bogus to me. The code should execute in exactly the
same way, wether assertions are turned on or off. If you don't have
enough confidence in the compiler to generate code that runs correctly,
why do you use a compiler at all? 
Yes I know compilers are buggy. Assertions within the compiler's source
code should help, but I also know this still cannot *guarantee*
correctness. But claiming "differences of behaviour with unbounded
consequences" overdoes it.

Regards,
Joachim
-- 
Please don't send unsolicited ads.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-19  0:00                   ` Robert A Duff
@ 1997-07-20  0:00                     ` Tucker Taft
  0 siblings, 0 replies; 255+ messages in thread
From: Tucker Taft @ 1997-07-20  0:00 UTC (permalink / raw)



Robert A Duff (bobduff@world.std.com) wrote:

: In article <JSA.97Jul18151414@alexandria.organon.com>,
: Jon S Anthony <jsa@alexandria.organon.com> wrote:
: >In article <EDHqKo.K52@world.std.com> bobduff@world.std.com (Robert A Duff) writes:
: >
: >> >> In article <JSA.97Jul13164937@alexandria.organon.com>, 
: >> >> jsa@alexandria.organon.com says...
: >> >> 
: >> >> >    type Require is boolean range True..True;
: >> >> >...
: >> >> >
: >> >> >    Assert : Require := Complex_Precondition(X);
: >> 
: >> This isn't quite right, because RM-11.6 allows the check to be
: >> eliminated.
: >
: >Bob, could you clarify this?

: Suppose Complex_Precondition(X) returns False.  Normally, you would
: expect a range check on the assignment, and that would raise C_E.
: However, 11.6(5) says the implementation does *not* have to raise C_E,
: since *in the absence of raising it*, the result has no external effect. ...

The way I like to think about 11.6(5) is that if a range-check fails, the
expression returns a special "undefined" value (equivalent to "bottom"
in some formal languages).  The compiler can then perform its normal
"dead assignment"/"dead variable" elimination on uses of this "undefined" 
value.  

For example, if you have a local variable that is assigned some
value, but then never used again, many compilers will remove the
assignment, and parts of the evaluation of the expression that have
no side effects (failing a language-defined check is *not* considered
a side-effect -- its effect is captured entirely in the "undefinedness"
of the result).

The purpose of raising an exception like Constraint_Error as a result 
of a check failure is to prevent some undefined value from causing
some externally visible "junk" output.  If the undefined value
makes no contribution to external output, then its calculation can
be removed like any other piece of dead code.  On the other hand,
if the undefined value is used as input to some external effect (which
includes any output, assigning into a volatile variable, passing to an
imported subprogram, returning from the main subprogram, etc.), then
an exception is raised to prevent the bad value from producing a bad
external effect.

The simplest way to use this rule is to mark the target of an assignment
as "volatile."  Alternatively, create a subprogram that stores its 
parameter into a volatile global of range True .. True, or that bumps
some global error counter (which you ultimately print out).

Or use "pragma Assert" which I believe is supported in almost all
Ada 95 compilers.


--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00           ` Joachim Durchholz
  1997-07-19  0:00             ` Ken Garlington
@ 1997-07-21  0:00             ` Robert S. White
  1997-07-20  0:00               ` nabbasi
  1 sibling, 1 reply; 255+ messages in thread
From: Robert S. White @ 1997-07-21  0:00 UTC (permalink / raw)



In article <33CD578D.562CC6A4@munich.netsurf.de>, 
joachim.durchholz@munich.netsurf.de says...
>

>changed anything. The issue is that the preconditions would have been an
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>integral part of the routine's signature, and thus not likely to have
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
>been overlooked by the team that ported the Ariane-4 code to Ariane-5.
 ^^^^^^^^^^^^^^^

  Wrong!  The code was _REUSED_ as is and nothing new was even looked 
at.  The systems engineers did not even allow for the chance of
a review/reading of embedded Ariane 4 preconditions in the software 
source code.  They don't read the Ada code and they would not have
read any Eiffel source code.  They should have reviewed and modified
the system requirements and then (somebody) showuld have flowed the 
changes down to the software requirements.  NOT A LANGUAGE ISSUE!


>As it were, the preconditions were buried in some obscure part of the
>documentation, and management didn't reread everything when they reused
>the code (together with its hardware).

  EXACTLY!   But the fight dynamics in a system requirements spec IS
NOT an  _obscure_ part of the documentation!
>
>The paper may not be very clear in this respect (I got Meyer's view on
>the topic from his book, not from the paper), or people might
>misinterpret what it's saying.
 
  Yes his sanctimonious preaching of this "Eiffel only" DBC 
"magic bullet" to practioners in this particular hard real-time 
safety-critical difficult INS/IRS software domain has raised our 
collective blood pressures.  It is not to say that DBC is not a 
good thing _When_ it can be readily applied.

>
>> According to Meyer, et. al. Eiffel programmers would have written the
>> handler
>> differently, and also they would have known to do the testing
>> differently (even though
>> the requirements specification said that the tests need not change).
>
>No. They would have written the handler the same way, and documented the
>precondition with the routine where it belongs, not in some obscure spec
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^
>sheets that are shelved away.

  You do _not_ know what your are talking about here.  This type of
requirement _MUST_ be in the software requirements document!!!

...rest of post deleted, stopping now, to let my blood pressure 
drop down.
_____________________________________________________________________
Robert S. White         -- An embedded systems software engineer





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-16  0:00             ` Robert Dewar
  1997-07-20  0:00               ` Joachim Durchholz
@ 1997-07-21  0:00               ` Don Harrison
  1 sibling, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-21  0:00 UTC (permalink / raw)



Robert Dewar wrote:

:The evaluation of any boolean expressoin has side effects at the level
:we are talking about, at the very least it takes time and can affect
:timing relationships, which of course in this kind of code can be
:critical.

Given that assertions are executed sequentially, there wouldn't appear to be 
any easy solution to this problem. The only options seem to be:

  a) Not using them at all, or
  b) Leaving them turned on in the production system. Obviously, this would
     mean efficiency problems.


:The idea that REMOVING the evaluation of boolean expressions completely
:is semantically neutral is also completely bogus. Such removal can affect
:Icache locality of the code that is left, again affecting timing, and can
:also result in code being at different locations, resulting in differences
:of behavior with unbounded consequences.

This issue would be avoided by b) above but the loss of efficiency would 
usually be unacceptable for hard realtime.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00             ` Robert Dewar
  1997-07-18  0:00               ` Jon S Anthony
@ 1997-07-21  0:00               ` Don Harrison
  1997-07-21  0:00                 ` Jon S Anthony
  1 sibling, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-21  0:00 UTC (permalink / raw)



Robert Dewar wrote:

:Don Harrison says
:
:<<Yes, I should have realised! It's the old workaround to the infuriating Ada83
:visibility problem of not being able to see the predefined operators of a user-d
:efined(?) type in client code. In spite of already with-ing the
:supplier module (which I don't think you should have to do, anyway - if you
:*use* features exported by a package, explicitly importing it is redundant),
:you can't see (hence, use) the imported operators.
:>>
:
:
:My goodness, surprising that anyone would think this, but then I guess there
:are people who really prefer uncontrolled anarchy.

No, that's what you get when you don't practise formal software engineering
where you need it. :)

However, your view is quite justified in the case of Ada which doesn't support 
well-specified, safe-to-use software components to the extent that Eiffel 
does. In view of this, you're quite justified in perceiving a need to document 
in one place all the modules used by another. In contrast, because Eiffel 
*does* support safe reuse of components, it isn't as important to separately 
document the modules used.

In any case, if you really want this in Eiffel, it's trivial to write an 
extraction tool to produce it. Implementations may already provide this.

:To me one of the real advantages in Ada is that you know right away, right
:at the start of the package, exactly what services are being used, 

See above.

:and you can more easily excercise control over this. 

This is not true unless you have a CM tool which allows you to separately
control the with-clauses of a package body and the rest of the body. I think
most will agree this would be ridiculous.

:If you let code anywwhere
:reach anywhere easily, you have a recipe for mess.

I agree for Ada. I don't agree for Eiffel which gives you a high level of 
confidence that you can reuse with impunity. Reusing certain modules may 
happen to be nonsensical but that's a design issue - not a reuse issue - and 
irrelevant to this argument.

:The requirement to write a with clause is also the requirement to think
:about whether it is appropriate for the unit you are in to "with" the
:unit that you think you need.

I disagree. An Eiffel software engineer thinks about this when they *use* a 
module. 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00             ` Karel Th�nissen
@ 1997-07-21  0:00               ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-21  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1111 bytes --]


Karel Th�nissen wrote:

:Don Harrison wrote:
:
:> Interestingly, this issue reveals a benefit of unifying module and type.
:> A unified model that dictates unique class names (eg. Eiffel's) simplifies
:> things by allowing class names to serve a twofold purpose in clients -
:> importing modules and entity (variable or routine parameter) declarations.
:> In one fell swoop, the need for import statements ("with"), visibility
:> statements ("use"), and module prefixes for diambiguation disappear.
:
:Correct, that this is unified in Eiffel, but the problem is pushed
:towards Lace: 

Agree.

:in Lace you do more or less the same as with and use in Ada.

I would have thought it was more like just "renames".

:You cannot have human-friendly names for classes/components if you also
:want to use classes written by third party vendors. There just is no way
:to avoid vendors from using identical symbolic names for their gadgets.
:So renaming and specification of classes used remains necessary.

Agree.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00                     ` Ken Garlington
@ 1997-07-21  0:00                       ` Paul Johnson
  0 siblings, 0 replies; 255+ messages in thread
From: Paul Johnson @ 1997-07-21  0:00 UTC (permalink / raw)



In article <33CFF256.61B4@flash.net>, kennieg@flash.net says...
>
>Paul Johnson wrote:

> How?  It sounds like you would have to have internal and external
>> versions of all routines, all suitably redefined in the presence of
>> inheritance.  This is not a trivial suggestion.

>Seems fairly trivial to me, particularly since I only have to worry
>about this in certain cases.

Hmmm.  I'd be interested to see a framework in Ada which lets you do all
the things with assertions that Eiffel does.  There is quite a lot of
stuff to do.  Some of it can be automated, some has to depend on coding
rules, and some requires new "special" variables or types (e.g. "require")
which will be recognised by language tools.  Any single part of the
Eiffel behaviour can be brought in fairly easily, but the whole thing
is starting to look rather clumsy.

>Since I can structure me system to only perform the invariant from
>an external call, this doesn't seem to be a big issue...

How does a routine distinguish between internal and external calls?

Or are you going to have two versions of each call?  An internal one
without assertion checks, and an external one which wraps the checks
around the internal one?  Or is there some nifty Ada Guru trick for
making this happen :-)

> The only difference is that Ada does internal
>checks by defaults, Eiffel requires extra code if you want the internal
>checks.

I'm not so sure about this.  Ada's main contribution to internal checks
are its subrange types.  I grant that declaring a subrange type is a bit
quicker and easier than putting an invariant in, but ultimately there
is not a lot of difference.

Meanwhile the emphasis on putting the interfaces to routines in their
assertions tends to reduce the number of explicit range checks required
on variables.  For instance array bound checks are carried out by
preconditions on the "array" routines.  Ada has a small edge here with
numeric data, but anything more complex presents problems.  To extend
the array subscript example, how would you express the fact that the
"item" routine of a hash table requires the argument value to be
contained in the hash table?  Eiffel just adds a "has(value)" 
precondition.

>You have to write the appropriate assertions in the ancestor, in
>either Ada or Eiffel.

>To repeat: Why do I have to _duplicate_ assertions in Ada?

Yes, but when you redefine the routine, you need to redefine its interface.
Software Contracting (the Eiffel approach to the LSP) states that you 
can:

1. Weaken the preconditions (so the routine may handle a wider range 
   of data,

2. Strengthen the postconditions (so the routine makes stronger guarantees
   about its effects).

To express this in Eiffel you use the "require else" and "ensure then"
clauses.  In Ada you would have to copy the pre and post conditions,
including the modifications.


>ah... assert : require := (a > b);
>
>However, this shouldn't be optimized out if an exception is possible, I
>don't think. (I'd have to go look back at chapter 11 to be sure...)

I believe you are correct.  Point conceeded.


>> I agree that timing variations can cause different results, but why would
>> they cause incorrect results?
>
>Because you made a mistake, of course! A mistake which will be hidden
>during
>your testing, but become (potentially fatally) obvious during
>operational use.
>This is considered a Bad Thing.

Umm.  Yes.  So bad that I would prefer a testing regime which at least
reduces the probability that it can occur.  How about a special stochastic
scheduler that simulates a wide variety of timing effects during testing.
I must confess I would have thought that this would be a good idea.  Lots
of things can cause timing changes.



>> [...] but why does the ability to enable and disable assertions
>> cause any new problems?
>
>Because I have seen compilers that generate correct code with one set of
>compiler options enabled, and a different (incorrect) set with a
>different set of options enabled. [...]
>Again, this is a Bad Thing for safety-critical systems.

Agreed.  I believe that the SCS people are looking at systems to verify
the object code against the source, as a way of getting around this problem
in general.  Of course the verifier may have bugs of its own, but it is
such a different piece of software to the compiler that the two bug sets
are unlikely to overlap.  Also it won't suffer from optimiser induced bugs.

Inheritance causes headaches here because you have to reconstruct the 
inheritance hierarchy from the optimised jump tables.  But then inheritance
causes problems in SCS anyway.


>Eiffel claims it's big advantage over other
>languages (including Ada) in this domain is stronger assertions. This is
>not a particularly useful claim if there are serious problems with using
>assertions extensively in such systems, is it?

Eiffel assertions are also part of the specification of classes.  It is
this that makes them significantly more powerful than Ada ranged types
and implementation assertions.

An Eiffel compiler is more likely to generate correct code with assertions
removed than with them enabled, because the code required for correct
assertion behaviour is quite complex.  However in the general case I
conceed your point.



>> Hence you have doubled the associated
>> work, and increased the risk of an error.  Eiffel requires that you write
>> the contract once, and uses the text for both purposes.
>
>Which is less writing, but may also require the user to see details that
>are not necessary. 

Such as?  I'm sorry, but I don't quite see what sort of details you 
have in mind.

Have you read Meyer's discussion of assertions and correctness in OOSC?
There are rules about this sort of thing (principally: the client must
be able to check the precondition before calling, and verify the
postcondition afterwards.  No private features are allowed in the public
assertions)

Paul.

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-07-21  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  1997-07-21  0:00 ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-07-21  0:00 UTC (permalink / raw)



Ken Garlington <kennieg@FLASH.NET> writes:
>> What does this have to do with the problem under discussion?  I agree that
>> this can happen, but why does the ability to enable and disable assertions
>> cause any new problems?
>
>Because I have seen compilers that generate correct code with one set of
>compiler options enabled, and a different (incorrect) set with a
>different
>set of options enabled. As with the timing issue above, I can do all of
>my testing with assertions enabled, and have no clue whether or not the
>code will still work after I disable those assertions (due to a compiler
>bug). Again, this is a Bad Thing for safety-critical systems.
>
    Let me ask a question about the way you work in your environment.
    I presume you have some group who is responsible for verification
    of whatever code you produce. Would they find it at all acceptable
    to change the contents of so much as one bit in an image without
    requiring some level of reverification of that image?

    We sort of tolerate *some* change, limited to a set of constants
    which need to be tuned for engine trim - sometimes overall trim
    for a type of engine, sometimes trim for a specific engine.
    (Depends on the project) But even then, the constants are given
    their own part number and are run through some abbreviated set of
    tests in the lab before being accepted as safe to send out the
    door.

    But the question of changing even a single word in the program
    image is unacceptable to our test group unless I can guarantee
    that by changing that word there is no conceivable way of causing
    the engine to come to harm or otherwise causing the control to
    malfunction. Since I can't do that, we never change an image in
    any way without reverification. Hence, verifying with compiler
    switch X set to "assertions enabled" then recompiling with switch
    X set to "assertions disabled" and presuming this is O.K. is not
    an option. Verification for us is also quite expensive and will
    eventually involve engine test stand time, so doing it twice is
    not economically viable.

    What I'd like to know is if we're unique in this requirement. Your
    IRS computers are also tasked with mission critical
    responsibilities and I'd like to get the thumbnail sketch as to
    what your verification and CM people find acceptable.

    MDC

Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
===============================================================================
    "You spend a billion here and a billion there. Sooner or later it
    adds up to real money."
        --  Everett Dirksen
===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-07-21  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  1997-07-21  0:00 ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-07-21  0:00 UTC (permalink / raw)



Ken Garlington <kennieg@FLASH.NET> writes:
>> Depends on the application.  Generally they print an error report, dump
>> stack information to a file, and ask the user to phone the vendor.  Note
>> that I am not proposing this for real-time embedded applications.  However
>> there are safety-critical applications which are not real-time.
>
>True. Furthermore, there are safety-critical real-time applications that
>are not required to be fail-operational. In both cases, I can at least
>see
>the glimmer of hope that assertions might have some value. (However,
>even
>a non-real-time system monitoring a nuclear power plant, for example,
>might
>not want to print out a message saying "phone the vendor, and I hope the
>reactor doesn't go supercritical while you're on hold :)
>
>However, for _at least_ certain classes of safety-critical systems, this
>behavior is completely unacceptable. Unfortunately, most people who
>advocate
>liberal use of exceptions are working on systems where it is quite
>acceptable.
>
    Well, here's one way of dealing with exceptions in a real-time
    safety critical application:

    If you have a control loop executing code, say, every 5mSec,
    sensing some inputs and doing some loop closure, you know by the
    rules of Ada that there are some exception possibilities you can't
    disable. Hence they could be raised by code beyond your control.
    You insert an exception handler in the loop to catch any of these,
    possibly logging them for telemetry (or at least ticking off a
    counter somewhere so you know it happened in lab testing!) then
    allow the loop to restart.

    What you're saying is this: "On pass N everything was fine. On
    pass N+1, something went haywire and interrupted normal execution.
    Because quitting operation is not an acceptable alternative, what
    I'm betting on is that on pass N+2, the problem will clear
    itself."

    This would potentially give you a viable use for raising
    exceptions on the fly. Granted, you wouldn't do this for any sort
    of expected conditions with planned for accommodations, but
    strictly for those sorts of errors that should never occur, but
    might just do so anyway. Your accommodation at that point might be
    something like resetting all of memory to its initial state and
    hoping that the next batch of inputs gets you back to where you
    should be.

    MDC

Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
===============================================================================
    "You spend a billion here and a billion there. Sooner or later it
    adds up to real money."
        --  Everett Dirksen
===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-19  0:00                 ` Robert A Duff
@ 1997-07-21  0:00                   ` W. Wesley Groleau x4923
  0 siblings, 0 replies; 255+ messages in thread
From: W. Wesley Groleau x4923 @ 1997-07-21  0:00 UTC (permalink / raw)



> Another pet peeve: In order to use Some_Package, you say "with
> Some_Package;".

I've often wondered whether the choice of "with" and "use" has any
relationship with the fact that one of the (losing) design teams was
the maintainer of UCSD Pascal.  In UCSD Pascal, "use" means EXACTLY
what "with" means in Ada, and Pascal's "with" is superficially similar
to Ada's "use"

-- 
----------------------------------------------------------------------
    Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA
Senior Software Engineer - AFATDS                  Tool-smith Wanna-be

Don't send advertisements to this domain unless asked!  All disk space
on fw.hac.com hosts belongs to either Hughes Defense Communications or 
the United States government.  Using email to store YOUR advertising 
on them is trespassing!
----------------------------------------------------------------------




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00           ` Robert I. Eachus
@ 1997-07-21  0:00             ` W. Wesley Groleau x4923
  0 siblings, 0 replies; 255+ messages in thread
From: W. Wesley Groleau x4923 @ 1997-07-21  0:00 UTC (permalink / raw)



>   > one more time what others said over and over: telling people to
>   > assert or document everything pertinent will NOT cure the failure
>   > to recognize what's pertinent!!
> 
>   True, but that didn't apply to the Ariane 5 case.  If you resuse
> software in an environment with very different requirements, ....

Well, IMHO, a difference in requirements is pertinent, and being 
told there is no difference is very nearly failing to recognize 
something pertinent!  :-)

-- 
----------------------------------------------------------------------
    Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA
Senior Software Engineer - AFATDS                  Tool-smith Wanna-be

Don't send advertisements to this domain unless asked!  All disk space
on fw.hac.com hosts belongs to either Hughes Defense Communications or 
the United States government.  Using email to store YOUR advertising 
on them is trespassing!
----------------------------------------------------------------------




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-20  0:00               ` nabbasi
@ 1997-07-21  0:00                 ` W. Wesley Groleau x4923
  0 siblings, 0 replies; 255+ messages in thread
From: W. Wesley Groleau x4923 @ 1997-07-21  0:00 UTC (permalink / raw)



> this is so funny. since when management "read" code and "use" code any way?

I once heard, "COBOL was designed to make it possible for managers to
read programs.  Instead, it successfully proved that managers don't 
read programs."

-- 
----------------------------------------------------------------------
    Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA
Senior Software Engineer - AFATDS                  Tool-smith Wanna-be

Don't send advertisements to this domain unless asked!  All disk space
on fw.hac.com hosts belongs to either Hughes Defense Communications or 
the United States government.  Using email to store YOUR advertising 
on them is trespassing!
----------------------------------------------------------------------




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-21  0:00               ` Don Harrison
@ 1997-07-21  0:00                 ` Jon S Anthony
  1997-07-21  0:00                   ` Brian Rogoff
  0 siblings, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-07-21  0:00 UTC (permalink / raw)



In article <EDnA6M.FGx@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> in one place all the modules used by another. In contrast, because
> Eiffel *does* support safe reuse of components, it isn't as
> important to separately document the modules used.

???  I don't think so.


> :If you let code anywwhere
> :reach anywhere easily, you have a recipe for mess.
> 
> I agree for Ada. I don't agree for Eiffel which gives you a high
> level of confidence that you can reuse with impunity. Reusing
> certain modules may happen to be nonsensical but that's a design
> issue - not a reuse issue - and irrelevant to this argument.

Come on Don, this problem is in Eiffel as well - it just doesn't offer
any support to fix it.  You have to punt out to something like LACE
which is just a hack.  A hack that works, but a hack nonetheless.

> :The requirement to write a with clause is also the requirement to think
> :about whether it is appropriate for the unit you are in to "with" the
> :unit that you think you need.
> 
> I disagree. An Eiffel software engineer thinks about this when they
> *use* a module.

Irrelevant.  The point is you can't just have "classes" - they do not
support large scale structures.  That's a bit part of why there even
is a LACE for crying out loud.


[[Aside: You know, Eiffel is a fairly decent language - not great, but
decent.  I'm with Brian Rogoff on this - all programming languages
suck.  And Eiffel sucks less than some but definitely more than
others.  IMO, it clearly sucks more than Ada, but people can disagree
on this as they both suck.  The big problem here is simply that many
Eiffel folk act as if it's a religion and sound very similar to the
sort of Ada fanatic that you used to run into.]]

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-21  0:00 Marin David Condic, 561.796.8997, M/S 731-96
@ 1997-07-21  0:00 ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-21  0:00 UTC (permalink / raw)



Marin David Condic, 561.796.8997, M/S 731-96 wrote:
> 
> Ken Garlington <kennieg@FLASH.NET> writes:
> >> What does this have to do with the problem under discussion?  I agree that
> >> this can happen, but why does the ability to enable and disable assertions
> >> cause any new problems?
> >
> >Because I have seen compilers that generate correct code with one set of
> >compiler options enabled, and a different (incorrect) set with a
> >different
> >set of options enabled. As with the timing issue above, I can do all of
> >my testing with assertions enabled, and have no clue whether or not the
> >code will still work after I disable those assertions (due to a compiler
> >bug). Again, this is a Bad Thing for safety-critical systems.
> >
>     Let me ask a question about the way you work in your environment.
>     I presume you have some group who is responsible for verification
>     of whatever code you produce. Would they find it at all acceptable
>     to change the contents of so much as one bit in an image without
>     requiring some level of reverification of that image?

No.

> 
>     We sort of tolerate *some* change, limited to a set of constants
>     which need to be tuned for engine trim - sometimes overall trim
>     for a type of engine, sometimes trim for a specific engine.
>     (Depends on the project) But even then, the constants are given
>     their own part number and are run through some abbreviated set of
>     tests in the lab before being accepted as safe to send out the
>     door.

Yes. We do the same thing, under the same conditions (in fact, on one
project I
work, the data file contains the expected version of the Pratt engine
software,
so that we can do on-board cross-checking of the environment
consistency!)

> 
>     But the question of changing even a single word in the program
>     image is unacceptable to our test group unless I can guarantee
>     that by changing that word there is no conceivable way of causing
>     the engine to come to harm or otherwise causing the control to
>     malfunction. Since I can't do that, we never change an image in
>     any way without reverification. Hence, verifying with compiler
>     switch X set to "assertions enabled" then recompiling with switch
>     X set to "assertions disabled" and presuming this is O.K. is not
>     an option. Verification for us is also quite expensive and will
>     eventually involve engine test stand time, so doing it twice is
>     not economically viable.

Exactly correct, as I said above.

> 
>     What I'd like to know is if we're unique in this requirement. Your
>     IRS computers are also tasked with mission critical
>     responsibilities and I'd like to get the thumbnail sketch as to
>     what your verification and CM people find acceptable.

Actually, I build flight controls that integrate with IRSs (and engines
:),
but we hold all three organizations to the process you describe. The
IRSs, by the say, are safety-critical on one project I work.

Say hello to Louie Celiberti for me!


> 
>     MDC
> 
> Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
> Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
> West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
> ===============================================================================
>     "You spend a billion here and a billion there. Sooner or later it
>     adds up to real money."
>         --  Everett Dirksen
> ===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-21  0:00 Marin David Condic, 561.796.8997, M/S 731-96
@ 1997-07-21  0:00 ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-21  0:00 UTC (permalink / raw)



Marin David Condic, 561.796.8997, M/S 731-96 wrote:
> 
> Ken Garlington <kennieg@FLASH.NET> writes:
> >> Depends on the application.  Generally they print an error report, dump
> >> stack information to a file, and ask the user to phone the vendor.  Note
> >> that I am not proposing this for real-time embedded applications.  However
> >> there are safety-critical applications which are not real-time.
> >
> >True. Furthermore, there are safety-critical real-time applications that
> >are not required to be fail-operational. In both cases, I can at least
> >see
> >the glimmer of hope that assertions might have some value. (However,
> >even
> >a non-real-time system monitoring a nuclear power plant, for example,
> >might
> >not want to print out a message saying "phone the vendor, and I hope the
> >reactor doesn't go supercritical while you're on hold :)
> >
> >However, for _at least_ certain classes of safety-critical systems, this
> >behavior is completely unacceptable. Unfortunately, most people who
> >advocate
> >liberal use of exceptions are working on systems where it is quite
> >acceptable.
> >
>     Well, here's one way of dealing with exceptions in a real-time
>     safety critical application:
> 
>     If you have a control loop executing code, say, every 5mSec,
>     sensing some inputs and doing some loop closure, you know by the
>     rules of Ada that there are some exception possibilities you can't
>     disable.

Realisitically, you can disable all of them (and we have in the past).

>     Hence they could be raised by code beyond your control.
>     You insert an exception handler in the loop to catch any of these,
>     possibly logging them for telemetry (or at least ticking off a
>     counter somewhere so you know it happened in lab testing!) then
>     allow the loop to restart.

Yes, we do this with interrupt handlers (although we resume where we
left off,
rather than restart). The problem with restart is blowing off a frame of
data.
For high-gain data, you might see a significant transient, which could
have very bad effects structurally, operationally, etc.

The bottom line is, there is no intrinsically "safe" general-purpose
approach
to handling exceptions. For the ones you can't suppress (or figure out
how to
handle otherwise), you end up basically making the best of a bad
situation.

> 
>     What you're saying is this: "On pass N everything was fine. On
>     pass N+1, something went haywire and interrupted normal execution.
>     Because quitting operation is not an acceptable alternative, what
>     I'm betting on is that on pass N+2, the problem will clear
>     itself."

OK for transient input problems (we use input filtering to handle those,
however),
or for transient hardware problems (and you should read the beating
Ariane
took for assuming that!), but there's absolutely no reason to assume a
software
design fault will act this way.

That's not to say that your approach is wrong, but if it fails... what
will your
inquiry board's report look like?

> 
>     This would potentially give you a viable use for raising
>     exceptions on the fly. Granted, you wouldn't do this for any sort
>     of expected conditions with planned for accommodations, but
>     strictly for those sorts of errors that should never occur, but
>     might just do so anyway. Your accommodation at that point might be
>     something like resetting all of memory to its initial state and
>     hoping that the next batch of inputs gets you back to where you
>     should be.

We actually have a top-level handler on some programs that does a warm
start
if a really serious event happens, that's similar to what you describe.
However, it's more of wishful thinking than anything else that says this
will save the system. It's the last line of defense, not the first, and
certainly
not something you want to depend on to say your system is safe!

> 
>     MDC
> 
> Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
> Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
> West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
> ===============================================================================
>     "You spend a billion here and a billion there. Sooner or later it
>     adds up to real money."
>         --  Everett Dirksen
> ===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-21  0:00                 ` Jon S Anthony
@ 1997-07-21  0:00                   ` Brian Rogoff
  0 siblings, 0 replies; 255+ messages in thread
From: Brian Rogoff @ 1997-07-21  0:00 UTC (permalink / raw)



On 21 Jul 1997, Jon S Anthony wrote:

> In article <EDnA6M.FGx@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:
> > I agree for Ada. I don't agree for Eiffel which gives you a high
> > level of confidence that you can reuse with impunity. Reusing
> > certain modules may happen to be nonsensical but that's a design
> > issue - not a reuse issue - and irrelevant to this argument.
> 
> Come on Don, this problem is in Eiffel as well - it just doesn't offer
> any support to fix it.  You have to punt out to something like LACE
> which is just a hack.  A hack that works, but a hack nonetheless.

	I am still amazed at this entire module class unification thing, 
but I think it is noteworthy that many languages which started their lives
without module systems acquired them, for example Perl, C++, Lisp, ML
dialects, etc. Sather, which began as an Eiffel knock off, will eventually
get one I've been told. Even Eiffel has one, it's just not standardized. 

	I think I can live with a language without an object system, but 
I'd have a much harder time living without modules distinct from types.

-- Brian





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-22  0:00               ` Don Harrison
@ 1997-07-21  0:00                 ` Ken Garlington
  1997-07-23  0:00                   ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-21  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> First, part of the reason it looks complicated is that it is only emulating
> (in Ada83) the real thing. As I've already said, I wouldn't implement assertions
> this way if I had the proper tools to work with. If you express it in Eiffel,
> it becomes simpler.

OK - could you post the Ada equivalent?

> Second, the compound condition represents a single higher level condition
> which can be declared as a function.

But doesn't that just postpone the complexity? Making the assertion
nearest
the point the reviewer is reading less clear, and requiring a search
through
other files to discover the meaning of the higher-level condition?

For that matter, if this is the correct method, why not do it in Ada?

> ..and lose the benefit of being able to execute it?

According to Meyer, the principle benefit is the documentation value.
As to execution (either during test or operation), see sections 3.2 and
3.3 of

   http://www.progsoc.uts.edu.au/~geldridg/eiffel/ariane/

> :... So, unless you propose teaching DBC
> :to all engineers in the program (which might not be a bad idea,
> :actually),
> 
> I agree, it would.

But unlikely, unfortunately, given the history of such attempts.

> I don't know what ADARTS is but it's one thing to be told you have to think
> of all assumptions and another to demonstrate you have as evidenced by coded
> assertions.

Again, from a documentation standpoint, why is writing code better than
documenting the assertions in a form the reviewer understands?

> 
> :I also challenge whether or not you code all of the assertions you can
> :envision.
> :Look at your example from earlier. There's absolutely no other
> :assertions you
> :could consider?
> 
> There may be others but so what? The existence of any I may not have thought
> of doesn't negate the effectiveness of those I *have* thought of.

But how do you draw the line between the assumptions you state and the
assumptions you leave silent?

And what does that do to the oft-said statement that Eiffel programmers
put in assertions for unlikely events?

> :How about the possibility that calling one of the
> :functions
> :in the assertion causes NO_OF_KEYS to become non-zero, just for fun?
> 
> As I don't write functions with side effects, I'm not sure why I would want to
> do that!..

More correctly stated, you don't _intend_ to write assumptions with side
effects, so you _assume_ there's no need to write an assertion to
confirm
that you, in fact, met your intent.

How do you catch software design faults in your code if you assume you
made
no mistakes in your code?

> Documented contracts are a good idea and may be appropriate for your domain.
> Their weakness is that they can't be enforced, so for *other* domains, I would
> prefer executable assertions.

A perfectly reasonable approach, for those domains that (a) can live
with
executable assertions and (b) where the documentation effect is best
expressed in code.

> There already was one, but it would be better to also have a higher level
> one for initialisation. This would aid testing in that if you fed in the
> wrong profile, you could verify that the IRS will not work. It wouldn't rely
> on the more obscure low-level assertion that was actually violated.
> 
> In IRS:
> 
>   set_operational_profile (profile: OPERATIONAL_PROFILE) is
>   require profile_compatible (profile)
>   do .. end

This would require that the profile be stored in memory, wouldn't it?
The profile is a textual/graphical description of the behavior of the
environment.

You might be able to express it as "The horizontal acceleration shall
not exceed xxx..." ... and in fact, it probably would make more sense
to express it exactly that way (in English!) so that it is clear at
the requirements level.

> BTW, this is intended to suggest what ought to done in engineering such
> software. This presupposes (among other things) that someone has actually sat
> down recognised the dependency of the IRS on the rocket dynamics. It is *not* a
> slap-on "remedy" to the non-existent software engineering that was practised
> in reality.
> 
> :  F-18     - divide by zero at Mach 1, due to incorrect control law
> :equation in spec.
> 
> There already was a predefined assertion for this - "you may not divide
> zero" - which presumably resulted in a numeric_error. This assertion correctly
> exposed an incorrect formula(?).

But how would the user write an Eiffel assertion to cover this? I know
that
Ada has pre-defined assertions, but how does the Eiffel coder write an
assertion that says "this equation has no errors?"

> 
> :  YF-22, Gripen - PIO due to incorrect control law equation in spec.
> :  (PIO is a complex lag interaction between the operator and the system -
> 
>   class SOME_CLASS
>     ...
>   invariant not PIO (..)
>   end
> 
> Likewise, this would expose the incorrect formula.

Unfortunately, PIO is not a formula, nor can it be sensed by the system.

It is an interaction between the
operator and the system. The system sees the operator telling it to
ascend, then descend, then ascend a little faster, then descend faster
still... which might be valid commands. However, what is actually
happening is that the pilot's sensory system is a little behind the
dynamics of the airframe. He's trying to level the aircraft, but
he's actually making the problem much worse. There are criteria that
can be used to analyze a system for such potential behavior, but
overcompensating for PIO can make the system too stable (not responsive
enough).

Try writing a post-condition that says, "user's favorite color
displayed on screen" (without being able to ask the user first) and
you'll see what I mean.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00       ` Don Harrison
@ 1997-07-22  0:00         ` Alan Brain
  1997-07-22  0:00           ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Alan Brain @ 1997-07-22  0:00 UTC (permalink / raw)



Don Harrison wrote:

> [Alan, I visited Le Rendezvous where we used to have pizza when we were at C3.
> Unfortunately, it's gone glitzy. What a shame! In the 11 years since then
> I still haven't found a Mexicana to match theirs.]

You might try Alex Cordobes in City Rd, Newtown.

It appears to me that the difference between Ada-95 and Eiffel is like
the difference between Airbags and Seatbelts. Both are great compared
with having neither. So it is with Pizzas, Cordobes or Le Rendezvous =
matter of opinion, but it's objectively provable that either are far
better than, say, Pizza the Hutt. 

-- 
aebrain@dynamite.com.au     <> <>    How doth the little Crocodile
| Alan & Carmel Brain|      xxxxx       Improve his shining tail?
| Canberra Australia |  xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM
100026.2014 compuserve o OO*O^^^^O*OO o oo     oo oo     oo  
                    By pulling MAERKLIN Wagons, in 1/220 Scale
See http://www.z-world.com/graphics/z/master/8856.gif for picture





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00 Marin David Condic, 561.796.8997, M/S 731-96
@ 1997-07-22  0:00 ` Karel Th�nissen
  0 siblings, 0 replies; 255+ messages in thread
From: Karel Th�nissen @ 1997-07-22  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1724 bytes --]


Marin David Condic, 561.796.8997, M/S 731-96 wrote:

[snip on the use of special assertions for timings]

>     It's a nice idea which, unfortunately can't be done. It's often
>     not well understood by those who are mostly used to some version
>     of workstation or pc based development why you can't test the code
>     with compiler option X then recompile you're code with options A,
>     B and C and pass it on as "production" software.

Sure, you only want to deliver as tested.

>     You might do this for some form of "informal" testing - maybe what
>     we took to calling "smoke testing". (Since all electronics works
>     on the principle of smoke - if you let the smoke out, it stops
>     working - the first test is to power it up and see if any smoke
>     comes out.) Under those conditions, you could compile any way you
>     like, find your problems, fix them and recompile for the "real"
>     tests.

Yes, smoke testing, I must remember that.
 
>     Once you start any sort of formal verification for a safety
>     critical system you cannot change any of the bits in the program
>     image without having to reverify the image. How much
>     reverification you do depends on lots of factors, but it's always
>     very expensive and you don't do it lightly.
> 
>     One other thing you want to consider is this: If the code *can*
>     run with runtime checks enabled, then you probably don't want to
>     turn it off for "production" anyway. What do you gain? The only
>     reason for turning it off is because it *can't* run with the
>     checks on.

Granted, but think of the additional weight of those assertions on board
of aircraft and spacecraft.

Groeten, Karel Th�nissen




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-22  0:00         ` Alan Brain
@ 1997-07-22  0:00           ` Don Harrison
  1997-07-23  0:00             ` Jon S Anthony
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-22  0:00 UTC (permalink / raw)



Alan Brain wrote:

:Don Harrison wrote:
:
:> [Alan, I visited Le Rendezvous where we used to have pizza when we were at C3.
:> Unfortunately, it's gone glitzy. What a shame! In the 11 years since then
:> I still haven't found a Mexicana to match theirs.]
:
:You might try Alex Cordobes in City Rd, Newtown.

Thanks. I'll bear that in mind.

:It appears to me that the difference between Ada-95 and Eiffel is like
:the difference between Airbags and Seatbelts. 

I'm paranoid - I'd like an airbag (static typing etc.) *and* a seatbelt 
(DBC etc.)!  :)

:Both are great compared
:with having neither. So it is with Pizzas, Cordobes or Le Rendezvous =
:matter of opinion, but it's objectively provable that either are far
:better than, say, Pizza the Hutt. 

:)  Absolutely!


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00             ` Robert Dewar
@ 1997-07-22  0:00               ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-22  0:00 UTC (permalink / raw)



Robert Dewar wrote:

:Don said
:
:<<Interestingly, this issue reveals a benefit of unifying module and type.
:A unified model that dictates unique class names (eg. Eiffel's) simplifies
:things by allowing class names to serve a twofold purpose in clients -
:>>
:
:
:Time to restate the following observation:
:
:Unify and Confuse both mean at their root the same thing, namely to
:make into one, or to join together, but they express a different
:judgment as to the desirability of of the joining.

Yes, the perspective *does* depend on a judgement of the desirability of 
unification vs. separation in any particular case considered. However, it's a
mistake to assume that a judgement is necessarily arbitrary. On the contrary, 
an informed judgement can be made on the basis of the relative pros/cons of 
each alternative. These pros and cons can be weighted on the basis of 
importance and used to construct a formula for desirability of unification/
separation. Among those qualities I would regard as important are such things 
as simplicity, reusability and reliability. Any rational person will agree 
these are important qualities in software. Pros which promote these qualities
would be heavily weighted as would be cons which compromised them.

Such a formula would provide a fairly objective basis for judgement which 
transcends the "This-is-what-I'm-used-to-so-it-must-be-better mentality".

I don't have the time to do this but it would be an instructive exercise 
given Eiffel's enhancement of the above qualities.


(Don certainly had nothing new to say on this issue, and neither
:do I :-)

There is more to say, but perhaps another day.. :)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-18  0:00             ` Ken Garlington
@ 1997-07-22  0:00               ` Don Harrison
  1997-07-21  0:00                 ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-22  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Again, someone needs to explain how these high-level assertions would
:have
:benefitted the Ariane 5 IRS.

I have almost zero interest in the Ariane failure because (as Robert Dewar 
correctly pointed out some time ago) it reveals next to nothing about software
engineering except what is blindingly obvious.


:> So, here's a different example. In my key handling object (one of the highest
:> level in the simulation), there's an operation for interpreting the CLEAR key.
:> Simplifying a little, pressing this key should reactivate the menu, clear the
:> key sequence and clear any menu or sub-menu selection. So, there's a compound
:> postcondition thus:
:> 
:>       if SA.ASSERTIONS_ON and then (INPUT_STATE /= MENU or else
:>         NO_OF_KEYS /= 0 or else MENU_OPTION_SELECTED or else
:>         SUBMENU_OPTION_SELECTED) then
:>         raise SA.POSTCONDITION_ERROR;
:> 
:> Note that some of the components are functions. Wrapping them in this way
:> is typical practice in Eiffel and enables you to use them elsewhere (eg. in
:> if-statements in the code proper) and makes contracting scalable.
:
:In Eiffel, I assume this code would be in the "short form." Is the
:user/reviewer
:really expected to read all of this (including looking up the functions
:embedded
:in this code) and understand it?

First, part of the reason it looks complicated is that it is only emulating 
(in Ada83) the real thing. As I've already said, I wouldn't implement assertions
this way if I had the proper tools to work with. If you express it in Eiffel, 
it becomes simpler. 

Second, the compound condition represents a single higher level condition 
which can be declared as a function.

So, expressing it in Eiffel and wrapping the compound condition, we have

  ensure in_menu_state

with function in_menu_state defined as

  in_menu_state: BOOLEAN is
  do
    Result := ...               -- compound condition
  end.

This should be simple enough for any reviewer. The meaning of in_menu_state 
is self explanatory but if they want more detail, they can look at its
implementation.

:Wouldn't it be just as easy to say, in the description of this
:operation, the
:English text preceding it?

..and lose the benefit of being able to execute it?


:... So, unless you propose teaching DBC
:to all engineers in the program (which might not be a bad idea,
:actually),

I agree, it would.


:> With regard to whether an Eiffel software engineer would have
:> picked up the false assumption compared with an Ada SE - possibly, due to the
:> fact that they are conditioned by their use of contracting to *think* of as
:> many assumptions as possible so they can code them as assertions. This sort of
:> conditioning is much less prevalent among Ada developers because most don't
:> use contracting (in this disciplined sense). I *know* this is true because I
:> work with them. Of course, they may be (and probably are) more disciplined
:> in your domain simply because they *have* to be. However, the conditioned
:> cultural difference due to disciplined contracting would be an advantage.
:
:Our engineers are taught the same thing in ADARTS, so I don;t think this
:is
:as big a difference as you think.

I don't know what ADARTS is but it's one thing to be told you have to think
of all assumptions and another to demonstrate you have as evidenced by coded 
assertions.

:I also challenge whether or not you code all of the assertions you can
:envision.
:Look at your example from earlier. There's absolutely no other
:assertions you
:could consider? 

There may be others but so what? The existence of any I may not have thought 
of doesn't negate the effectiveness of those I *have* thought of.

:How about the possibility that calling one of the
:functions
:in the assertion causes NO_OF_KEYS to become non-zero, just for fun?

As I don't write functions with side effects, I'm not sure why I would want to
do that!..


:> For your domain it's a bit of a Catch-22. Contracting would improve the culture
:> but you're unable to use it due to hard timing constraints.
:
:Not at all. We have to distinguish between "contracting" and
:"assertions." You
:can still think in terms of writing strong interfaces, with well
:documented
:user constraints (ADARTS term), but without coding them. For example,
:you may
:write your test cases such that pre-conditions, post-conditions, and
:invariants
:are checked outside the object code. You can also permit more
:comprehensive
:reviews by documenting them via comments. The point is, you don't have
:to use
:DBC/Eiffel to get these benefits... they are also contained in
:ADARTS/Ada, for
:example.

Documented contracts are a good idea and may be appropriate for your domain.
Their weakness is that they can't be enforced, so for *other* domains, I would 
prefer executable assertions.


:> No, it's the conditioning that makes the difference. There are a lot of
:> Ada software engineers who *are* serious about quality (including you, I expect).
:> Using DBC just makes you more effective.
:
:However, the supposed advantage of Eiffel is that this thinking becomes
:code.
:I don't see the advantage for my domain (although I certainly do for
:others).

Agree.

[...]


:> Can you give an example? Not sure how high-level you mean.
:
:Recent examples:
:
:  Ariane 5 - incorrect operational profile (Ariane 4 specified instead
:of 5)
:             See:
:http://www.esrin.esa.it/htdocs/tidc/Press/Press96/ariane5rep.html

There already was one, but it would be better to also have a higher level 
one for initialisation. This would aid testing in that if you fed in the 
wrong profile, you could verify that the IRS will not work. It wouldn't rely
on the more obscure low-level assertion that was actually violated.

In IRS:

  set_operational_profile (profile: OPERATIONAL_PROFILE) is
  require profile_compatible (profile)
  do .. end

BTW, this is intended to suggest what ought to done in engineering such 
software. This presupposes (among other things) that someone has actually sat 
down recognised the dependency of the IRS on the rocket dynamics. It is *not* a 
slap-on "remedy" to the non-existent software engineering that was practised 
in reality.

:  F-18     - divide by zero at Mach 1, due to incorrect control law
:equation in spec.

There already was a predefined assertion for this - "you may not divide 
zero" - which presumably resulted in a numeric_error. This assertion correctly
exposed an incorrect formula(?).

:  YF-22, Gripen - PIO due to incorrect control law equation in spec.
:  (PIO is a complex lag interaction between the operator and the system -

  class SOME_CLASS
    ...
  invariant not PIO (..)
  end

Likewise, this would expose the incorrect formula.


:Aren't there more fundamental problems than just this? You state that
:the assertions can't be executed in a hard real-time thread, so how does
:a "realtime" library help?

For those that aren't.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                   ` Ken Garlington
@ 1997-07-23  0:00                     ` Don Harrison
  1997-07-23  0:00                       ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-23  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Richie Bielak wrote:

:> I always thought it would be nice to have postconditions of the form:
:> 
:>         ensure
:>                 execution_time < 10 -- 10 milliseconds, let's say
           end
           ^^^
           my addition
:> 
:> So an exception would be raised if the routine took too long
:> to execute.
:
:Of course, you have to decide if "execution time" includes the time for
:the postcondition (including any code that executes after the actual
:test instruction)!

It would be the duration when the expression "execution_time" is evaluated.
There would be no statements following the assertion so it should be accurate 
enough for most purposes. If not, you can apply a small compensating adjustment 
to the relational expression:

         ensure
                 execution_time < 9.99  -- milliseconds
         end


:We usually have such measurements _outside_ the code sequence being
:measured (i.e., in the scheduler).

..in which case, you'd presumably be subject to the timing inaccuracies of 
the scheduler, anyway.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                 ` Richie Bielak
                                     ` (2 preceding siblings ...)
  1997-07-17  0:00                   ` Samuel Tardieu
@ 1997-07-23  0:00                   ` Don Harrison
  1997-07-23  0:00                     ` Ken Garlington
  3 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-23  0:00 UTC (permalink / raw)



Richie Bielak wrote:

:I always thought it would be nice to have postconditions of the form:
:
:	ensure
:		execution_time < 10 -- 10 milliseconds, let's say
:
:So an exception would be raised if the routine took too long
:to execute.

I've also been thinking along these lines since about a year ago. It sits very 
well with DBC, IMO.

Also, the idea of express messages in SCOOP caters for the situation where
a time-critical thread *must* execute without fail. 

(For more information, see Object-oriented Software Construction (2nd ed.) 
Section 30.8 - "Requesting Special Service").


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-17  0:00                     ` Richie Bielak
@ 1997-07-23  0:00                       ` Don Harrison
  1997-07-23  0:00                         ` Jon S Anthony
                                           ` (2 more replies)
  0 siblings, 3 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-23  0:00 UTC (permalink / raw)



Richie Bielak wrote:

:Samuel Tardieu wrote:
:
:[...]
:> 
:> Well, I find the corresponding Ada code readable enough:
:> 
:>    select
:>       delay 0.010;               --  The 10ms you were talking about
:>       raise Timeout_Failure;     --  Raise an exception, or do anything else
:>                                  --  you need (use a fast version of
:>                                  --  your computation for example).
:>    then abort
:>       [...your code here...]     --  This piece of code will be
:>                                  --  aborted if it is not terminated within
:>                                  --  the 10ms you required above.
:>    end select;
:> 
:
:That's neat. Except that a postcondition will be part of the contract
:(i.e. specification) for the routine, so the caller will know what to 
:expect. Your code is part of the implementation.

I agree - it's belongs in a contract.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                       ` Don Harrison
  1997-07-23  0:00                         ` Jon S Anthony
  1997-07-23  0:00                         ` Ken Garlington
@ 1997-07-23  0:00                         ` Karel Th�nissen
  1997-07-24  0:00                           ` Don Harrison
  2 siblings, 1 reply; 255+ messages in thread
From: Karel Th�nissen @ 1997-07-23  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2170 bytes --]


Don Harrison wrote:
> 
> Richie Bielak wrote:
> 
> :Samuel Tardieu wrote:
> :
> :[...]
> :>
> :> Well, I find the corresponding Ada code readable enough:
> :>
> :>    select
> :>       delay 0.010;               --  The 10ms you were talking about
> :>       raise Timeout_Failure;     --  Raise an exception, or do anything else
> :>                                  --  you need (use a fast version of
> :>                                  --  your computation for example).
> :>    then abort
> :>       [...your code here...]     --  This piece of code will be
> :>                                  --  aborted if it is not terminated within
> :>                                  --  the 10ms you required above.
> :>    end select;
> :>
> :
> :That's neat. Except that a postcondition will be part of the contract
> :(i.e. specification) for the routine, so the caller will know what to
> :expect. Your code is part of the implementation.
> 
> I agree - it's belongs in a contract.

I think it only belongs in a contract if the timing of an method
invocation is concerned. However, this avenue of the thread was started
with the observation that a program should not depend on timing in an
unspecified/undocumented way.

The execution time of a method is one thing we need to time, and for
this the postcondition is the proper place.

However, there are a lot more things we may have to time, but that are
not directly linked to a particular (interface of) an object. For
example:

- the timing between two iterations of a loop
- the interval between two read outs of a memory mapped IO-port
- the timing of the execution of a method where the timing is critical
  on the part of the calling method and not of the called method itself
- timing of the interaction with the user (which is not a method for
  which one can specify a contract)
- timing of a number of instructions within a method
- etc.

So even though timing specifications with postconditions are useful, it
definitely is not sufficient for many HRT systems.

-- 
Groeten, Karel Th�nissen

-- my e-mail address is scrambled to confuse spammers
-- remove the confusion to obtain my true address




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                   ` Don Harrison
  1997-07-23  0:00                     ` Ken Garlington
@ 1997-07-23  0:00                     ` W. Wesley Groleau x4923
  1997-07-24  0:00                       ` Don Harrison
  1 sibling, 1 reply; 255+ messages in thread
From: W. Wesley Groleau x4923 @ 1997-07-23  0:00 UTC (permalink / raw)



> Consider the aversion of developers to documenting code. It's viewed by them
> as a necessary burden which doesn't actually make the software work so there's
> little motivation to do it. ....

I hope this is not generally true, and I don't think it is.  I think
that 
there are far too many that think that way, but OTOH even more just let 
the documentation slide due to real or perceived schedule pressure.  
Either way it's a Bad Thing.

> little motivation to do it. Executable assertions, OTOH, actually contribute
> something (runtime checks) to a running program. Therefore, they have some
> material value in the mind of a developer and their more likely to use them.
> The by-product is that the code gets documented for free and the developers
> actually *want* to do it.

And either way, this part is a Good Thing--if it doesn't also slide 
for the same reasons.

> :And what does that do to the oft-said statement that Eiffel programmers
> :put in assertions for unlikely events?
> 
> That's what all (or at least most) assertions are. They're catering for the
> unlikely event that the developer has made a logic error. Most of the time
> we write code with correct logic but occasionally we make mistakes. These
> mistakes can often be picked up by an assertion.

This is a good idea for most software.  But I would think that if you 
know enough to write the assertion, you know enough to track down and 
eliminate whatever would make the assertion fail.  In safety-critical 
software, how can you justify not doing so? 

-- 
----------------------------------------------------------------------
    Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA
Senior Software Engineer - AFATDS                  Tool-smith Wanna-be

Don't send advertisements to this domain unless asked!  All disk space
on fw.hac.com hosts belongs to either Hughes Defense Communications or 
the United States government.  Using email to store YOUR advertising 
on them is trespassing!
----------------------------------------------------------------------




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-22  0:00           ` Don Harrison
@ 1997-07-23  0:00             ` Jon S Anthony
  1997-07-24  0:00               ` Don Harrison
  1997-07-25  0:00               ` Alan Brain
  0 siblings, 2 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-23  0:00 UTC (permalink / raw)



In article <EDquzz.EK4@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> :It appears to me that the difference between Ada-95 and Eiffel is like
> :the difference between Airbags and Seatbelts. 
> 
> I'm paranoid - I'd like an airbag (static typing etc.) *and* a seatbelt 
> (DBC etc.)!  :)

Actually, I think you have that backwards: seatbelts (typing, system
validity, etc.) and airbag (DBC).  Just like where airbags are noted
as being somewhat useful when used with seatbelts, but not
particularly useful (even dangerous) without seatbelts.

/Jon

-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                       ` Don Harrison
@ 1997-07-23  0:00                         ` Jon S Anthony
  1997-07-24  0:00                           ` Don Harrison
  1997-07-23  0:00                         ` Ken Garlington
  1997-07-23  0:00                         ` Karel Th�nissen
  2 siblings, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-07-23  0:00 UTC (permalink / raw)



In article <EDrGL0.DD2@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Richie Bielak wrote:
> 
> :Samuel Tardieu wrote:
> :
> :[...]
> :> 
> :> Well, I find the corresponding Ada code readable enough:
> :> 
> :>    select
> :>       delay 0.010;               --  The 10ms you were talking about
> :>       raise Timeout_Failure;     --  Raise an exception, or do anything else
> :>                                  --  you need (use a fast version of
> :>                                  --  your computation for example).
> :>    then abort
> :>       [...your code here...]     --  This piece of code will be
> :>                                  --  aborted if it is not terminated within
> :>                                  --  the 10ms you required above.
> :>    end select;
> :> 
> :
> :That's neat. Except that a postcondition will be part of the contract
> :(i.e. specification) for the routine, so the caller will know what to 
> :expect. Your code is part of the implementation.
> 
> I agree - it's belongs in a contract.

That is trivial to provide:

function Do_Something_Within_Time_Slice (
    ...
    Duration_Before_Abort : Our_Duration_Limits := 0.010;
    ...
    ) return Whatever_Type;


/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                       ` Don Harrison
  1997-07-23  0:00                         ` Jon S Anthony
@ 1997-07-23  0:00                         ` Ken Garlington
  1997-07-25  0:00                           ` Don Harrison
  1997-07-23  0:00                         ` Karel Th�nissen
  2 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-23  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Richie Bielak wrote:
> 
> :Samuel Tardieu wrote:
> :
> :[...]
> :>
> :> Well, I find the corresponding Ada code readable enough:
> :>
> :>    select
> :>       delay 0.010;               --  The 10ms you were talking about
> :>       raise Timeout_Failure;     --  Raise an exception, or do anything else
> :>                                  --  you need (use a fast version of
> :>                                  --  your computation for example).
> :>    then abort
> :>       [...your code here...]     --  This piece of code will be
> :>                                  --  aborted if it is not terminated within
> :>                                  --  the 10ms you required above.
> :>    end select;
> :>
> :
> :That's neat. Except that a postcondition will be part of the contract
> :(i.e. specification) for the routine, so the caller will know what to
> :expect. Your code is part of the implementation.
> 
> I agree - it's belongs in a contract.

However, if this is an actor task, there is no contract (in any
language;
it would not be called explicitly by other parts of the application). If
it
is an agent or server task, the comment shown above would be associated
in
the task specification with the particular entry(ies) it affected.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                   ` Don Harrison
@ 1997-07-23  0:00                     ` Ken Garlington
  1997-07-25  0:00                       ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-23  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Richie Bielak wrote:
> 
> :I always thought it would be nice to have postconditions of the form:
> :
> :       ensure
> :               execution_time < 10 -- 10 milliseconds, let's say
> :
> :So an exception would be raised if the routine took too long
> :to execute.
> 
> I've also been thinking along these lines since about a year ago. It sits very
> well with DBC, IMO.

This would work if there is an inherent time limit to the object's
functionality.
It won't work if the issue is the contribution to the object to a thread
of
execution, particularly if the object is going to support multiple
threads. The
issue of specifying absolute time in an environment where objects are
reused
in future applications is also a sticking point. ADARTS does thread
timeline
analysis independently of object interface specification, which in my
experience makes more sense.

> 
> Also, the idea of express messages in SCOOP caters for the situation where
> a time-critical thread *must* execute without fail.
> 
> (For more information, see Object-oriented Software Construction (2nd ed.)
> Section 30.8 - "Requesting Special Service").
> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                   ` Don Harrison
@ 1997-07-23  0:00                     ` Ken Garlington
  1997-07-25  0:00                       ` Don Harrison
  1997-07-23  0:00                     ` W. Wesley Groleau x4923
  1 sibling, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-23  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :Don Harrison wrote:
> :>
> :> First, part of the reason it looks complicated is that it is only emulating
> :> (in Ada83) the real thing. As I've already said, I wouldn't implement assertions
> :> this way if I had the proper tools to work with. If you express it in Eiffel,
> :> it becomes simpler.
> :
> :OK - could you post the Ada equivalent?
> 
> Sure. Assuming the availability of a postcondition clause,
> 
>   type Input_State_Type is (.., Menu, ..);
> 
>   Input_State : Input_State_Type;
>   No_of_Keys : Natural
>   Menu_Option_Selected : Boolean;
>   Submenu_Option_Selected : Boolean;
> 
>   ...
> 
>   function in_menu_state return Boolean is
>   begin
>     return (Input_State = Menu and then No_of_Keys = 0 and then
>       not Menu_Option_Selected and then not Submenu_Option_Selected);
>   end;
> 
>   procedure Interpret_CLR_Key is
>   begin
>     ...
>   ensure in_menu_state                                   -- General assertion
>   end;
> 
> Note that there is no precondition on Interpret_CLR_Key in accordance with the
> fact that the Console Operator should be able to press any key at any time
> without having the software fall over. Using assertions to validate input
> would be a misuse of DBC.

Compare this to the Ada code you presented earlier. Why is this
significantly
simpler or easier to read?

> 
> :> Second, the compound condition represents a single higher level condition
> :> which can be declared as a function.
> :
> :But doesn't that just postpone the complexity? Making the assertion
> :nearest
> :the point the reviewer is reading less clear, and requiring a search
> :through
> :other files to discover the meaning of the higher-level condition?
> 
> Yes, but this is no different from using encapsulation for abstraction anywhere
> else to simplify. You aren't going to replace every call in a procedure
> with the actual code of the called procedures (a compiler may, but a human
> shouldn't). Neither should you do this for assertions. You don't suddenly forget
> about abstraction just because you're writing an assertion.

True, but remember that we are asking a human reader to not just
understand what is required from a user's point of view (where
abstraction
permits unncessary details to be hidden), but to verify if the
software will function correctly or not. Doesn't this imply that the
evaluator will likely have to understand more than that required by a
user of
the interface?

> A prerequisite for (any kind of) abstraction to be effective, of course, is
> meaningful identifiers. If your identifier names accurately reflect what you're
> trying to model, a high-level assertion immediately makes sense and you only
> look further if you really need to know the details. This would be the case,
> for example, if investigating the cause of an assertion violation or conducting
> a manual code review. 

Exactly my point. Meyer claims that such manual reviews are the primary
benefit
of assertions. However, abstration does not necessarily assist such a
review; in
fact, it may complicate it.

> Otherwise, the higher-level abstraction is not only
> sufficient but desirable (unless you want to be needlessly swamped by compexity).
> 
> Using meaningful identifiers sure makes a big difference to intelligibility and,
> IMO, is a skill that can be acquired by any reasonably literate developer
> who is suitably encouraged (read "forced" to use them).

However, if the intent is to discover errors made by the developer, to
what
extent can the reviewer trust those "meaningful identifiers"?

> :For that matter, if this is the correct method, why not do it in Ada?
> 
> Purely historical reasons. If the code wasn't frozen at the moment, I probably
> would.

Then this doesn't seem to be an advantage of Eiffel over Ada, as your
earlier comment indicated.

> 
> :>: Wouldn't it be just as easy to say, in the description of this
> :>: operation, the
> :>: English text preceding it?
> :>
> :> ..and lose the benefit of being able to execute it?
> :
> :According to Meyer, the principle benefit is the documentation value.
> 
> I don't know whether he said this, but I'm not sure that I agree. I'll only
> find out through experience..

See section 3.1 of my analysis of his Ariane paper, at:

   http://www.progsoc.uts.edu.au/~geldridg/eiffel/ariane/

> :As to execution (either during test or operation), see sections 3.2 and
> :3.3 of
> :
> :   http://www.progsoc.uts.edu.au/~geldridg/eiffel/ariane/
> 
> This is irrelevant to what we are dicussing here - use of DBC in non-HRT
> situations. It should be quite plain by now that I agree with you about the
> dangers of using assertions in HRT threads using current technology.
> 
> :> :... So, unless you propose teaching DBC
> :> :to all engineers in the program (which might not be a bad idea,
> :> :actually),
> :>
> :> I agree, it would.
> :
> :But unlikely, unfortunately, given the history of such attempts.
> 
> Quite true.
> 
> :> I don't know what ADARTS is but it's one thing to be told you have to think
> :> of all assumptions and another to demonstrate you have as evidenced by coded
> :> assertions.
> :
> :Again, from a documentation standpoint, why is writing code better than
> :documenting the assertions in a form the reviewer understands?
> 
> Consider the aversion of developers to documenting code. It's viewed by them
> as a necessary burden which doesn't actually make the software work so there's
> little motivation to do it. Executable assertions, OTOH, actually contribute
> something (runtime checks) to a running program. Therefore, they have some
> material value in the mind of a developer and their more likely to use them.

I'm not sure I agree that well-trained and professional developers feel
this
way, but let's say they do. Wouldn't this imply that they will be biased
toward adding code that helps them get their code correct for the
current
use of their code (i.e. that part that provides direct value to them)
and
much less attention to addressing issues that don't provide value to
them
(e.g., handling errors due to improper reuse by "some other guy")?

> The by-product is that the code gets documented for free and the developers
> actually *want* to do it.

It also seems that the documentation value of the assertions will be
lessened
(less likely to use meaningful identifiers vs. ones that "work good
enough").
The line between codes that don't like to write documentation vs. coders
that
don't like to write self-documenting code for others to read appears to
me
to be easy to cross...

> 
> :> :I also challenge whether or not you code all of the assertions you can
> :> :envision.
> :> :Look at your example from earlier. There's absolutely no other
> :> :assertions you
> :> :could consider?
> :>
> :> There may be others but so what? The existence of any I may not have thought
> :> of doesn't negate the effectiveness of those I *have* thought of.
> :
> :But how do you draw the line between the assumptions you state and the
> :assumptions you leave silent?
> 
> Sorry, not sure what you're driving at.

Every error condition that might occur (e.g., adding extra code that
makes an extraneous assignment), but is not checked by an assertion,
would appear to be an undocumented assumption. Every undocumented
assumption,
per Meyer, represents an incomplete description of the interface.

How do you decide which assumptions not to document?

> :And what does that do to the oft-said statement that Eiffel programmers
> :put in assertions for unlikely events?
> 
> That's what all (or at least most) assertions are. They're catering for the
> unlikely event that the developer has made a logic error. Most of the time
> we write code with correct logic but occasionally we make mistakes. These
> mistakes can often be picked up by an assertion.

So, how are the likely events detected?

And, if the same person who made the logic error writes the assertions,
why
is it reasonable to expect that the assertion detects the error? Won't
the person simply make the same mistake in logic, particularly for such
things as missed requirements?

> :> :How about the possibility that calling one of the
> :> :functions
> :> :in the assertion causes NO_OF_KEYS to become non-zero, just for fun?
> :>
> :> As I don't write functions with side effects, I'm not sure why I would want to
> :> do that!..
> :
> :More correctly stated, you don't _intend_ to write assumptions with side
> :effects, so you _assume_ there's no need to write an assertion to
> :confirm
> :that you, in fact, met your intent.
> 
> You mean meta-assertions? Obviously, Your question in tongue-in-cheek but
> does highlight the fact that there is practical limit beyond which you don't
> want to go and meta-assertions are well beyond that limit. Most people want to
> go home at the end of the day.

I don't know why this is a "meta-assertion." Extraneous code is a
category of
error, just like missing code.

Given that "most people want to go home at the end of the day," my point
stands.
Which assumptions do you document? Which do you remain undocumented? And
what
theory drives the decision? Does DBC say, "this type of coding error is
more
likely than the other, so protect against it first?"

> :How do you catch software design faults in your code if you assume you
> :made
> :no mistakes in your code?
> 
> Don't follow. In writing assertions, you assume you *will* make design mistakes
> in the code proper.

Except that you deliberately exclude classes of faults, apparently,
without
any statement in the code that you did so.

> If you're talking about design faults in assertions, I've
> already answered you previously - the code proper acts as a built-in assertion
> validation mechanism.

Think again, particularly with respect to missing code.

> 
> :> Documented contracts are a good idea and may be appropriate for your domain.
> :> Their weakness is that they can't be enforced, so for *other* domains, I would
> :> prefer executable assertions.
> :
> :A perfectly reasonable approach, for those domains that (a) can live
> :with
> :executable assertions and (b) where the documentation effect is best
> :expressed in code.
> 
> Agree.
> 
> :> There already was one, but it would be better to also have a higher level
> :> one for initialisation. This would aid testing in that if you fed in the
> :> wrong profile, you could verify that the IRS will not work. It wouldn't rely
> :> on the more obscure low-level assertion that was actually violated.
> :>
> :> In IRS:
> :>
> :>   set_operational_profile (profile: OPERATIONAL_PROFILE) is
> :>   require profile_compatible (profile)
> :>   do .. end
> :
> :This would require that the profile be stored in memory, wouldn't it?
> :The profile is a textual/graphical description of the behavior of the
> :environment.
> 
> No, it simply requires that the thing you want to make assertions about can
> be abstracted in some way. This implies both attributes (data) and operations
> on those attributes. If you can abstract a profile using a class (which I'm
> sure you could), then you can make assertions about it's compatibility.

Don't assertions involving the enviroment require data about the
environment?

> 
> :You might be able to express it as "The horizontal acceleration shall
> :not exceed xxx..." ... and in fact, it probably would make more sense
> :to express it exactly that way (in English!) so that it is clear at
> :the requirements level.
> 
> You can do both.

I'm not sure I agree with the claim that all comments can be written as
code!

> 
> The other examples actually aren't applicable to the efficacy of DBC as
> they stem from errors in specification documents..

WUPS!

DBC doesn't protect against errors in specification documents? An
interesting
statement!

Given this, then it shouldn't be able to protect against
misinterpretations
of specification documents by a developer, either, true? Or, for that
matter,
misinterpretations of any higher-tier document (e.g. a design document)?
Doesn't
a requirement not read equate to a requirement not written?

Finally, of all of the errors in code, assuming the use of existing
techniques
(code reviews, unit test, etc.) how many are "code-only" errors vs.
misinterpretations
of higher-tier documents?

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                     ` Don Harrison
@ 1997-07-23  0:00                       ` Ken Garlington
  1997-07-25  0:00                         ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-23  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :Richie Bielak wrote:
> 
> :> I always thought it would be nice to have postconditions of the form:
> :>
> :>         ensure
> :>                 execution_time < 10 -- 10 milliseconds, let's say
>            end
>            ^^^
>            my addition
> :>
> :> So an exception would be raised if the routine took too long
> :> to execute.
> :
> :Of course, you have to decide if "execution time" includes the time for
> :the postcondition (including any code that executes after the actual
> :test instruction)!
> 
> It would be the duration when the expression "execution_time" is evaluated.
> There would be no statements following the assertion so it should be accurate
> enough for most purposes. 

1. Why would there be no statements afterwards?
2. If there were assertions _before_ this one, would their time be
included?
3. How is the assumption "accurate enough" captured in an Eiffel
assertion? (_Would_
it be captured?)

> If not, you can apply a small compensating adjustment
> to the relational expression:
> 
>          ensure
>                  execution_time < 9.99  -- milliseconds
>          end

However, this compensation depends upon making assumptions of the
time it takes to do the assertions... and we want to avoid writing code
whose correctness depends upon assumptions about how fast the code runs,
right?

> 
> :We usually have such measurements _outside_ the code sequence being
> :measured (i.e., in the scheduler).
> 
> ..in which case, you'd presumably be subject to the timing inaccuracies of
> the scheduler, anyway.

But the timing inaccuracies of the scheduler are at the thread level.
Your
inaccuracies are at the object level. If a lot of objects are called in
the course of a thread's execution (or a few are called a lot of times),
your inaccuracies build. Mine don't (particularly if the start of the
thread is controlled by a high-accuracy timer/low-overhead interrupt
handler, which is typical for hard real-time systems).

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-21  0:00                 ` Ken Garlington
@ 1997-07-23  0:00                   ` Don Harrison
  1997-07-23  0:00                     ` Ken Garlington
  1997-07-23  0:00                     ` W. Wesley Groleau x4923
  0 siblings, 2 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-23  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> First, part of the reason it looks complicated is that it is only emulating
:> (in Ada83) the real thing. As I've already said, I wouldn't implement assertions
:> this way if I had the proper tools to work with. If you express it in Eiffel,
:> it becomes simpler.
:
:OK - could you post the Ada equivalent?

Sure. Assuming the availability of a postcondition clause,

  type Input_State_Type is (.., Menu, ..);

  Input_State : Input_State_Type;
  No_of_Keys : Natural
  Menu_Option_Selected : Boolean;
  Submenu_Option_Selected : Boolean;

  ...

  function in_menu_state return Boolean is
  begin
    return (Input_State = Menu and then No_of_Keys = 0 and then 
      not Menu_Option_Selected and then not Submenu_Option_Selected);
  end;

  procedure Interpret_CLR_Key is
  begin
    ...
  ensure in_menu_state                                   -- General assertion
  end;

Note that there is no precondition on Interpret_CLR_Key in accordance with the
fact that the Console Operator should be able to press any key at any time 
without having the software fall over. Using assertions to validate input 
would be a misuse of DBC.


:> Second, the compound condition represents a single higher level condition
:> which can be declared as a function.
:
:But doesn't that just postpone the complexity? Making the assertion
:nearest
:the point the reviewer is reading less clear, and requiring a search
:through
:other files to discover the meaning of the higher-level condition?

Yes, but this is no different from using encapsulation for abstraction anywhere 
else to simplify. You aren't going to replace every call in a procedure 
with the actual code of the called procedures (a compiler may, but a human 
shouldn't). Neither should you do this for assertions. You don't suddenly forget 
about abstraction just because you're writing an assertion.

A prerequisite for (any kind of) abstraction to be effective, of course, is
meaningful identifiers. If your identifier names accurately reflect what you're
trying to model, a high-level assertion immediately makes sense and you only 
look further if you really need to know the details. This would be the case, 
for example, if investigating the cause of an assertion violation or conducting 
a manual code review. Otherwise, the higher-level abstraction is not only 
sufficient but desirable (unless you want to be needlessly swamped by compexity).

Using meaningful identifiers sure makes a big difference to intelligibility and, 
IMO, is a skill that can be acquired by any reasonably literate developer 
who is suitably encouraged (read "forced" to use them). 
 

:For that matter, if this is the correct method, why not do it in Ada?

Purely historical reasons. If the code wasn't frozen at the moment, I probably
would.


:>: Wouldn't it be just as easy to say, in the description of this
:>: operation, the
:>: English text preceding it?
:>
:> ..and lose the benefit of being able to execute it?
:
:According to Meyer, the principle benefit is the documentation value.

I don't know whether he said this, but I'm not sure that I agree. I'll only 
find out through experience..

:As to execution (either during test or operation), see sections 3.2 and
:3.3 of
:
:   http://www.progsoc.uts.edu.au/~geldridg/eiffel/ariane/

This is irrelevant to what we are dicussing here - use of DBC in non-HRT 
situations. It should be quite plain by now that I agree with you about the 
dangers of using assertions in HRT threads using current technology.


:> :... So, unless you propose teaching DBC
:> :to all engineers in the program (which might not be a bad idea,
:> :actually),
:> 
:> I agree, it would.
:
:But unlikely, unfortunately, given the history of such attempts.

Quite true.


:> I don't know what ADARTS is but it's one thing to be told you have to think
:> of all assumptions and another to demonstrate you have as evidenced by coded
:> assertions.
:
:Again, from a documentation standpoint, why is writing code better than
:documenting the assertions in a form the reviewer understands?

Consider the aversion of developers to documenting code. It's viewed by them 
as a necessary burden which doesn't actually make the software work so there's 
little motivation to do it. Executable assertions, OTOH, actually contribute 
something (runtime checks) to a running program. Therefore, they have some 
material value in the mind of a developer and their more likely to use them.
The by-product is that the code gets documented for free and the developers
actually *want* to do it.


:> :I also challenge whether or not you code all of the assertions you can
:> :envision.
:> :Look at your example from earlier. There's absolutely no other
:> :assertions you
:> :could consider?
:> 
:> There may be others but so what? The existence of any I may not have thought
:> of doesn't negate the effectiveness of those I *have* thought of.
:
:But how do you draw the line between the assumptions you state and the
:assumptions you leave silent?

Sorry, not sure what you're driving at. 

:And what does that do to the oft-said statement that Eiffel programmers
:put in assertions for unlikely events?

That's what all (or at least most) assertions are. They're catering for the 
unlikely event that the developer has made a logic error. Most of the time 
we write code with correct logic but occasionally we make mistakes. These 
mistakes can often be picked up by an assertion.


:> :How about the possibility that calling one of the
:> :functions
:> :in the assertion causes NO_OF_KEYS to become non-zero, just for fun?
:> 
:> As I don't write functions with side effects, I'm not sure why I would want to
:> do that!..
:
:More correctly stated, you don't _intend_ to write assumptions with side
:effects, so you _assume_ there's no need to write an assertion to
:confirm
:that you, in fact, met your intent.

You mean meta-assertions? Obviously, Your question in tongue-in-cheek but 
does highlight the fact that there is practical limit beyond which you don't 
want to go and meta-assertions are well beyond that limit. Most people want to 
go home at the end of the day.


:How do you catch software design faults in your code if you assume you
:made
:no mistakes in your code?

Don't follow. In writing assertions, you assume you *will* make design mistakes
in the code proper. If you're talking about design faults in assertions, I've
already answered you previously - the code proper acts as a built-in assertion
validation mechanism.


:> Documented contracts are a good idea and may be appropriate for your domain.
:> Their weakness is that they can't be enforced, so for *other* domains, I would
:> prefer executable assertions.
:
:A perfectly reasonable approach, for those domains that (a) can live
:with
:executable assertions and (b) where the documentation effect is best
:expressed in code.

Agree.


:> There already was one, but it would be better to also have a higher level
:> one for initialisation. This would aid testing in that if you fed in the
:> wrong profile, you could verify that the IRS will not work. It wouldn't rely
:> on the more obscure low-level assertion that was actually violated.
:> 
:> In IRS:
:> 
:>   set_operational_profile (profile: OPERATIONAL_PROFILE) is
:>   require profile_compatible (profile)
:>   do .. end
:
:This would require that the profile be stored in memory, wouldn't it?
:The profile is a textual/graphical description of the behavior of the
:environment.

No, it simply requires that the thing you want to make assertions about can 
be abstracted in some way. This implies both attributes (data) and operations
on those attributes. If you can abstract a profile using a class (which I'm
sure you could), then you can make assertions about it's compatibility.

:You might be able to express it as "The horizontal acceleration shall
:not exceed xxx..." ... and in fact, it probably would make more sense
:to express it exactly that way (in English!) so that it is clear at
:the requirements level.

You can do both.


The other examples actually aren't applicable to the efficacy of DBC as 
they stem from errors in specification documents..


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-20  0:00               ` Joachim Durchholz
@ 1997-07-24  0:00                 ` Joe Buck
  1997-07-24  0:00                 ` Paul M Gover
  1 sibling, 0 replies; 255+ messages in thread
From: Joe Buck @ 1997-07-24  0:00 UTC (permalink / raw)




Robert Dewar wrote:
>> The idea that REMOVING the evaluation of boolean expressions
>> completely
>> is semantically neutral is also completely bogus.

Joachim Durchholz <joachim.durchholz@munich.netsurf.de> writes:
>That's a bit strong.

In real-time systems, it isn't strong; it has to be taken into account.

>> Such removal can affect
>> Icache locality of the code that is left, again affecting timing,
>
>OK. Is an issue for real-time software where code timing is important.
>I'm somewhat astonished that such code is still written (the last time I
>saw this done was on a C64), but then I'm not in the hard RT field.

This statement suggests that your perspective is too narrow.  You
encounter hard real-time systems every day.  Far more processors in the
world are running embedded real-time code than are running your favorite
PC program.  It is exactly these systems that it is most critical to get
right; people could die if they fail (anti-lock braking systems,
fly-by-wire systems in AirBus planes, industrial robots).  No one much
cares if your Unix app core dumps.  Timing constraints are often quite
tight; a telephone-bandwidth speech compression system has to produce one
sample every 125 microseconds, all the time, or the user hears a pop.
Caches are often of no use, since it is the worst case timing (the cache
miss) that counts.  If your system has to meet timing even if you take a
cache miss, why spend money on the cache?  (Instruction caches can still
pay because you may be guaranteed that your loop fits in the cache).

In practice, these problems are manageable; what matters is the timing of
critical paths, not of all paths.  But in many cases adding assertion
checks will result in a program that does not meet its deadlines, so you
need some other means (like a second processor or emulation testbench that
observes the processor under test, with assertion checks running on this
other processor).

>> and can also result in code being at different locations, resulting in
>> differences of behavior with unbounded consequences.

>Now *that* sounds bogus to me. The code should execute in exactly the
>same way, wether assertions are turned on or off. If you don't have
>enough confidence in the compiler to generate code that runs correctly,
>why do you use a compiler at all? 

All compilers have bugs, and all responsible software engineers test the
object code they are going to ship, not just different object code that has
debug code and assertions stuck in.  There's a term "Heisenbug", a bug
that disappears when you enable debugging because the compiler generates
different code when debugging is enabled.
-- 
-- Joe Buck	http://www.synopsys.com/pubs/research/people/jbuck.html

Help stamp out Internet spam: see http://spam.abuse.net/spam/




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00             ` Jon S Anthony
@ 1997-07-24  0:00               ` Don Harrison
  1997-07-25  0:00               ` Alan Brain
  1 sibling, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-24  0:00 UTC (permalink / raw)



Jon S Anthony wrote:

:In article <EDquzz.EK4@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:
:
:> :It appears to me that the difference between Ada-95 and Eiffel is like
:> :the difference between Airbags and Seatbelts. 
:> 
:> I'm paranoid - I'd like an airbag (static typing etc.) *and* a seatbelt 
:> (DBC etc.)!  :)
:
:Actually, I think you have that backwards: seatbelts (typing, system
:validity, etc.) and airbag (DBC).  Just like where airbags are noted
:as being somewhat useful when used with seatbelts, but not
:particularly useful (even dangerous) without seatbelts.

Yes, quite true. If I *had* to choose between static typing and DBC, I would 
choose static typing.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                           ` Don Harrison
  1997-07-24  0:00                             ` Ken Garlington
@ 1997-07-24  0:00                             ` Don Harrison
  1 sibling, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-24  0:00 UTC (permalink / raw)



A point of clarification. I wrote:

:       !!a.make

As previously discussed, for realtime systems, the overhead of dynamic memory 
allocation can be removed by using a pre-allocated pool. For an HRT system, you 
can go a step further and remove the dynamic binding by freezing the routine 
used to create.


Note also that:

a) There is no equivalent for some of these timing assertions in Ada - in 
   particular, timing invariants.

b) For those that *are* emulatable in Ada, there is effectively *no extra* 
   runtime overhead from using assertions compared with the equivalent Ada.
   Where Ada offers a built-in mechanism, as for task time-outs, the overhead
   is hidden within the mechanism.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                         ` Karel Th�nissen
@ 1997-07-24  0:00                           ` Don Harrison
  1997-07-24  0:00                             ` Ken Garlington
  1997-07-24  0:00                             ` Don Harrison
  0 siblings, 2 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-24  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 5159 bytes --]


Karel Th�nissen wrote:

:Don Harrison wrote:

:> I agree - it's belongs in a contract.
:
:I think it only belongs in a contract if the timing of an method
:invocation is concerned. 

I don't agree. I'll outline what we *can* do and then address your specific 
examples.

1) We can time how long it takes for a method to execute using a postcondition:

     do_something (.., time_started: TIME) is
     do
       ...
     ensure (time_now - time_started <= allowable_duration) <<<<
     end

   (We agree on this). 

2) You can time the periodicity (time between drinks) of a call using a 
   precondition and an attribute of the enclosing class which records the time 
   last called:

     class SOME_CLASS 
     creation make
     feature
       do_something (..) is
       require 
         not called_before or else (time_now - time_last_called <= max_duration) <<<<
       do 
         time_last_called := time_now
         called_before := TRUE
         ...
       end

       make is
       do called_before := FALSE; end

     feature {NONE}
       time_last_called: TIME
       called_before: BOOLEAN
     end

3) You can time how long it takes to perform any action within the body of a 
   routine using a check-instruction and a local attribute recording the time
   the action started:

 a)  do_something (..) is
     local time_started: TIME
     do
       ...
       time_started := time_now
       ... -- timed action
       check (time_now - time_started < max_duration) end <<<<
       ...
     end

   Note that the check-instruction can appear anywhere so can be used to time
   a conditional branch or the average duration of a loop iteration:

 b)  time_started := time_now
     no_of_iterations := 0
     loop
       no_of_iterations := no_of_iterations + 1
       ...
     end
     check 
       (time_now - time_started) / no_of_iterations <= max_iteration_duration <<<<
     end

4) You can time the periodicity of calls made by a caller by using a 
   check-instruction and an attribute in the caller's class which records the 
   time the last call was made:

     class CALLING_CLASS 
     creation make
     feature
       ...
       !!a.make
       ...
       check 
         not called_before or else (time_now - time_of_last_call <= max_duration) <<<<
       end
       time_of_last_call := time_now
       a.do_something -- the call
       ...

       make is
       do called_before := FALSE; end

     feature {NONE}
       a: CALLED_CLASS
       time_of_last_call: TIME
       called_before: BOOLEAN
     end

5) You can ensure that no call made by a caller takes longer than a specified 
   duration by using an invariant and an attribute in the caller's class which 
   records the time a call was made:

     class CALLING_CLASS 
     feature
       ...
       !!a.make
       ...
       time_started := time_now
       a.do_something -- the call
       ...

     feature {NONE}
       a: CALLED_CLASS
       time_started: TIME

     invariant
       time_now - time_started <= max_duration <<<<
     end

6) You can ensure that no call made to a callee takes longer than a specified 
   duration by using an invariant and an attribute in the enclosing class which 
   records the time a call was made:

   (Details omitted - similar to 5) ).


:However, this avenue of the thread was started
:with the observation that a program should not depend on timing in an
:unspecified/undocumented way.

I agree. However, I think you'll agree on the basis of the examples above,
Eiffel assertions are a powerful means of, not only specifying and documenting 
timing dependencies, but validating at runtime that they're complied with.


:... there are a lot more things we may have to time, but that are
:not directly linked to a particular (interface of) an object. 

Correct - hence the need for check-instructions.


For example:
:
:- the timing between two iterations of a loop

  See 3) b) above.

:- the interval between two read outs of a memory mapped IO-port

  See 4) above.

:- the timing of the execution of a method where the timing is critical
:  on the part of the calling method and not of the called method itself

  See 4) above.

:- timing of the interaction with the user (which is not a method for
:  which one can specify a contract)

  Nor should we. No action (or not taken by a user) should ever be the basis 
  of an assertion. Such cases should be catered for by logic in the code 
  proper because are not indicative of errors in the software. A couple of 
  examples are a) user input validation and b) failure of a pilot to take 
  remedial action (or taking too much remedial action - Ken's example).

:- timing of a number of instructions within a method

  See 3) a) above.

 - timing of any call made by an object

  See 5) above.

 - timing of any call made to an object

  See 6) above.


:So even though timing specifications with postconditions are useful, it
:definitely is not sufficient for many HRT systems.

Agree, you also need preconditions, check-instructions and invariants.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                         ` Jon S Anthony
@ 1997-07-24  0:00                           ` Don Harrison
  1997-07-24  0:00                             ` Jon S Anthony
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-24  0:00 UTC (permalink / raw)



Jon S Anthony wrote:

:In article <EDrGL0.DD2@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:
:
:> Richie Bielak wrote:
:> 
:> :Samuel Tardieu wrote:
:> :
:> :[...]
:> :> 
:> :> Well, I find the corresponding Ada code readable enough:
:> :> 
:> :>    select
:> :>       delay 0.010;               --  The 10ms you were talking about
:> :>       raise Timeout_Failure;     --  Raise an exception, or do anything else
:> :>                                  --  you need (use a fast version of
:> :>                                  --  your computation for example).
:> :>    then abort
:> :>       [...your code here...]     --  This piece of code will be
:> :>                                  --  aborted if it is not terminated within
:> :>                                  --  the 10ms you required above.
:> :>    end select;
:> :> 
:> :
:> :That's neat. Except that a postcondition will be part of the contract
:> :(i.e. specification) for the routine, so the caller will know what to 
:> :expect. Your code is part of the implementation.
:> 
:> I agree - it's belongs in a contract.
:
:That is trivial to provide:
:
:function Do_Something_Within_Time_Slice (
:    ...
:    Duration_Before_Abort : Our_Duration_Limits := 0.010;
:    ...
:    ) return Whatever_Type;

Sorry, I don't see how this acheives anything resembling the Eiffel contract..


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-20  0:00               ` Joachim Durchholz
  1997-07-24  0:00                 ` Joe Buck
@ 1997-07-24  0:00                 ` Paul M Gover
  1997-07-26  0:00                   ` Joachim Durchholz
  1 sibling, 1 reply; 255+ messages in thread
From: Paul M Gover @ 1997-07-24  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:
> ...
> Now *that* sounds bogus to me. The code should execute in exactly the
> same way, wether assertions are turned on or off. If you don't have
> enough confidence in the compiler to generate code that runs correctly,
> why do you use a compiler at all?
> ...

(Sorry if I''m about to repeat an earlier part of this discussion - I've
not followed this thread in detail,)

By definition, the code executes differently depending on whether
asserions
are turned on or off - because the assertion checking _is_ code!
In particular, there's likely to be some memory management going on in
an
OO system.  Two possibilities: we could run out of memory in the
assertion,
or the memory management might take too long for some critical signal.

(And to direct a slight breeze towards some other embers, it doesn't
make
a difference if the OO system uses garbage collection or not; as Chamond
Liu
pointed out (see http://www.browsebooks.com/Liu/Chapter16.html),
garbage collectors tend to have predictable allocation times and 
unpredictable free (ie, collection) times, whereas heap allocation tends
to have unpredictable allocation times and predictable free times;
garbage collection systems have to search storage at collection time,
and heaps search at allocation time.)

I currently support a program where switching the diagnostic trace on
breaks part of the user interface (since the program's correct,
I don't need to trace, so I don't need to fix the bug!?!).
This one is definitely an application fault, nothing to do with the
compiler.
-- 
Paul Gover
IBM Warwick Development Group
Mumbling for myself, not IBM




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-07-24  0:00 Marin David Condic, 561.796.8997, M/S 731-96
  0 siblings, 0 replies; 255+ messages in thread
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-07-24  0:00 UTC (permalink / raw)



Ken Garlington <kennieg@FLASH.NET> writes:
>>     If you have a control loop executing code, say, every 5mSec,
>>     sensing some inputs and doing some loop closure, you know by the
>>     rules of Ada that there are some exception possibilities you can't
>>     disable.
>
>Realisitically, you can disable all of them (and we have in the past).
>
    Seems like the last time I checked the Ada83 standard when my
    project had an issue with this, there were some cases where
    disabling the checks would have been difficult and probably
    unwise. (I'm thinking specifically of PROGRAM_ERROR, STORAGE_ERROR
    and TASKING_ERROR. Given the sorts of things that can raise these
    errors, they may be beyond your direct control. Of course, you may
    get some variance based on compilers.) Where there's a whip,
    there's a way, so I'll agree you can turn off all exceptions,
    albeit you may get stuck doing some tweeking of your RTK. (Doesn't
    scare me - just makes one more thing I've got to document & test.)

>>     Hence they could be raised by code beyond your control.
>>     You insert an exception handler in the loop to catch any of these,
>>     possibly logging them for telemetry (or at least ticking off a
>>     counter somewhere so you know it happened in lab testing!) then
>>     allow the loop to restart.
>
>Yes, we do this with interrupt handlers (although we resume where we
>left off,
>rather than restart). The problem with restart is blowing off a frame of
>data.
>For high-gain data, you might see a significant transient, which could
>have very bad effects structurally, operationally, etc.
>
    Interrupt handlers are a similar, but different enough to warrant
    some special consideration. First off, you *can* return to where
    you left off with an interrupt - not so with exceptions. (I'm sure
    you realize this, but it needed to be stated.) We took this view
    of interrupts: Some we were using and they had some appropriate
    code to do what needed to be done. Others we weren't using, so
    they were masked off. In the off chance that some mysterious code
    messed up the mask or gamma rays punched holes in the mask at the
    same instant that a spurious interrupt happened, we had handlers
    tied to the unused interrupts "just in case". You could presume
    that the most probable cause of receiving one of these interrupts
    was a hardware failure of some sort - which may have been either
    transient or permanent. Software *might* have caused it
    (accidentally performed some XIO instructions with the wrong
    addresses & data which just so happened to unmask, then trigger an
    interrupt?) and again you could presume it was either transient or
    permanent. So the catch-all handlers were designed to log the
    error, report it in telemetry and if it was the third occurrence,
    presume something was broke permanently and transfer control to
    the other side.

    You could devise a dozen variants for accommodating these errors,
    all of which have strengths & weaknesses - but eventually you've
    got to fly with only one of them and live with it's weaknesses. In
    any event, if the interrupt was occurring from a flaw in the
    software design - well you're truly intercoursed and there's no way
    around it when the design is "common mode". It's the same deal you
    get with identical processor board designs - if some transistor is
    plugged into the design to operate at it's ragged edge limit of
    failure and some corner case drives the transistor just a little
    harder than that, you let the smoke out. Guess what? The same
    transistor on the other side is seeing the same corner case and
    it's probably letting the smoke out too. Kiss the rocket goodbye.

>The bottom line is, there is no intrinsically "safe" general-purpose
>approach
>to handling exceptions. For the ones you can't suppress (or figure out
>how to
>handle otherwise), you end up basically making the best of a bad
>situation.
>
    True. We looked at them and used the outer-most-loop scheme I
    outlined. Again the accommodation was *usually* to log it three
    times, then shut down presuming the channel to be broke. This was
    the general philosophy for all our system level FDA - not just
    exceptions. Some, we reasoned might be fixed by reloading out of
    E**2, so we'd reboot after the transfer. Some errors we'd presume
    broken hardware and stay down. Some, the three occurrences would
    have to be in a row - if it cleared for a given cycle, you'd reset
    the counters. All of it had to be based on an analysis of the
    errors we could detect and looking at the most probable cause,
    then deriving a reasonable accommodation. However, you can't fix
    everything, right? What if the processor gets fried by gamma rays?
    What's your software going to do to clear *that* problem?
    (Seriously got asked that question!) What if the common mode
    design is flawed? What if the sun expands suddenly and totally
    engulfs the rocket in fire? Some things you can't fix with
    software.
>>
>>     What you're saying is this: "On pass N everything was fine. On
>>     pass N+1, something went haywire and interrupted normal execution.
>>     Because quitting operation is not an acceptable alternative, what
>>     I'm betting on is that on pass N+2, the problem will clear
>>     itself."
>
>OK for transient input problems (we use input filtering to handle those,
>however),
>or for transient hardware problems (and you should read the beating
>Ariane
>took for assuming that!), but there's absolutely no reason to assume a
>software
>design fault will act this way.
>
>That's not to say that your approach is wrong, but if it fails... what
>will your
>inquiry board's report look like?
>
    Agreed. Software design faults are probably the most difficult to
    accommodate because a) you don't know what it's going to do so you
    don't even know if you can detect it and b) unless you know what
    it's nature is you can't devise a reasonable accommodation. (And
    if I knew what it's nature was, I'd probably have gotten rid of it
    and insured that it would never happen anyway!) Our approach with
    the outer-loop exception handler was based on some assumptions: If
    something goes wrong for which you don't already have some
    accommodation (the stuff you didn't know about) then it is
    probably better for the control to press on trying to run the
    system than it would be to shut down and leave the engine
    fail-fixed. If the problem is serious enough not to clear,
    eventually your watchdog timer is going to shut the channel down
    anyway (or some other FDA is going to come into play) and you
    *probably* didn't do any harm by continuing to try to run.

    For transient data problems and such, we'd naturally go do some
    form of input filtering, range checking, invalid input logic,
    whatever. But that's all for the errors you know about and
    anticipate. The toughies are the ones you *don't* know about and
    *don't* anticipate. Those are always the ones that kill you. And I
    don't know of any design strategy or theory or rule of thumb
    method that's going to help you with the problems that fit in this
    category.
>>
>>     This would potentially give you a viable use for raising
>>     exceptions on the fly. Granted, you wouldn't do this for any sort
>>     of expected conditions with planned for accommodations, but
>>     strictly for those sorts of errors that should never occur, but
>>     might just do so anyway. Your accommodation at that point might be
>>     something like resetting all of memory to its initial state and
>>     hoping that the next batch of inputs gets you back to where you
>>     should be.
>
>We actually have a top-level handler on some programs that does a warm
>start
>if a really serious event happens, that's similar to what you describe.
>However, it's more of wishful thinking than anything else that says this
>will save the system. It's the last line of defense, not the first, and
>certainly
>not something you want to depend on to say your system is safe!

    You're right - it's wishful thinking. But if the alternative is to
    shut down the system and let the rocket fall in the ocean - well
    the mission's over anyway, you might just as well try *something*,
    no matter how desparate.

    I agree, it's the last resort - not the first line of defense. But
    I don't think most of us would run off raising exceptions for
    things we could easily detect and accommodate as we're reading the
    data and making our computations. Given that little Ariane event,
    I'd think that if you went to all the trouble of putting in the
    assertion to range check the input, you might just as well have
    saturated the number and set the "bad data" flag riding with it.
    (assuming we're redesigning the system). Our practical experience
    with control systems indicates that saturated arithmetic most
    often "does the right thing" for out of range situations.

    But again, this is all 20/20 hindsight and as I've observed
    before, the Ariane software was an adequate design in it's
    original context.

    MDC

Marin David Condic, Senior Computer Engineer     ATT:        561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:        561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:   CONDICMA@PWFL.COM
===============================================================================
    "They can't get you for what you didn't say."
        --  Calvin Coolidge
===============================================================================




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                     ` W. Wesley Groleau x4923
@ 1997-07-24  0:00                       ` Don Harrison
  1997-07-24  0:00                         ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-24  0:00 UTC (permalink / raw)



Wesley Groleau wrote:

:> Consider the aversion of developers to documenting code. It's viewed by them
:> as a necessary burden which doesn't actually make the software work so there's
:> little motivation to do it. ....
:
:I hope this is not generally true, and I don't think it is.  I think
:that 
:there are far too many that think that way, but OTOH even more just let 
:the documentation slide due to real or perceived schedule pressure.  
:Either way it's a Bad Thing.

Agree.


:> little motivation to do it. Executable assertions, OTOH, actually contribute
:> something (runtime checks) to a running program. Therefore, they have some
:> material value in the mind of a developer and their more likely to use them.
:> The by-product is that the code gets documented for free and the developers
:> actually *want* to do it.
:
:And either way, this part is a Good Thing--if it doesn't also slide 
:for the same reasons.

Agree.


:> :And what does that do to the oft-said statement that Eiffel programmers
:> :put in assertions for unlikely events?
:> 
:> That's what all (or at least most) assertions are. They're catering for the
:> unlikely event that the developer has made a logic error. Most of the time
:> we write code with correct logic but occasionally we make mistakes. These
:> mistakes can often be picked up by an assertion.
:
:This is a good idea for most software.  But I would think that if you 
:know enough to write the assertion, you know enough to track down and 
:eliminate whatever would make the assertion fail.  

This is true only in a few isolated cases. However, what we come up against 
more often is an exponential complexity caused by the number of possible 
execution paths to the routine we are dealing with at any one time. While we
can comfortably grapple with the logic of the actual routine at hand and 
a handful of the more isolated execution paths, we usually haven't a hope 
of dealing with all possible execution paths. There are very few people who 
can handle complexity of these dimensions and they probably prefer to use it 
playing chess with Deep Blue or counting cards in casinos than in developing 
software.

So, disappointed, we admit we're not up to the task of dealing with all the 
possibilities in the system as a whole. What we remember, though, is that 
we're more than capable of dealing with just our routine - that's no problem.
Well, if we can't cope with the system as a whole, how about doing it 
incrementally. If we can prove, step-by-step that each part of the system is
doing the right thing, then we've got the problem beaten - a divide-and-conquer
strategy. Let's think about how we might be able to do that..

To do that, we'll suppose we're developing an Air Traffic Control system 
and we have a concept of aircraft which may be transfered from one controller 
to another. The specific part of the overall ATC system we want to consider
is an operation Assume_Control which takes an Aircraft as a parameter.

So, we have

  procedure Assume_Control (Aircraft: Aircraft_Type) is
  begin
    ...
    My_Aircraft.Add (Aircraft);   -- Add to my set of aircraft
  end;

Well, that's simple enough. Not much can go wrong here ..or can it? We see 
a couple of potential problems:

  1) What if I already control the aircraft and, by mistake, the software that
     tranfers control doesn't realise it? It's likely that our software will 
     corrupt some data, for example leaving us with a duplicate aircraft under
     our control!

  2) We delegate work to other objects to get the job done. What if one of 
     them makes a mistake? Then, by implication, there's also a mistake in *our*
     operation!

We need some way to stop these things happening. 

For 1), we could add a comment to the operation header

       -- Assumes aircraft not already controlled

so the transfer software knows to check this first. That's good but still leaves 
us a little uneasy. Even though the requirement is documented, it's still 
possible to miss or ignore it. We could protect ourselves by checking *ourselves*
that the aircraft is not already controlled by us..

  begin
    if not My_Aircraft.Mine (Aircraft) then
      ...
      My_Aircraft.Add (Aircraft);
    end if;
  end;

That would mean *we're* okay, but what about the caller? There is a serious 
problem here in that the caller's code contains an error. They are calling 
an operation they don't need to. This is misleading and may lead to further 
errors in the caller based on the assumed contextual validity of the call.
Also, the erroneous call will cause problems if, for some reason, the 
implementation of our operation changes so it is no longer benign under these 
conditions. 

What we want is a way to signal to the caller that they've made a mistake and 
need to take corrective action. A very effective way of doing that is by 
raising an exception. This sends a very clear message which cannot be ignored.

So, we add a mechanism to the language whereby we can make the checks *and* 
raise an exception if not satisfied..

  procedure Assume_Control (Aircraft: Aircraft_Type) is
  require not My_Aircraft.Mine (Aircraft)
  begin
    ...
    My_Aircraft.Add (Aircraft);
  end;

Now our operation can only be executed under the right circumstances.

What about case 2)? Here, we want to check that the work we delegated was 
done properly and acheived what we set out to do. In this case, we can 
perform some checks and raise and exception against ourselves to force us 
to fix the problem (possibly by delegating)..

  procedure Assume_Control (Aircraft: Aircraft_Type) is
  require not My_Aircraft.Mine (Aircraft)
  begin
    ...
    My_Aircraft.Add (Aircraft);
  ensure My_Aircraft.Mine (Aircraft)
  end;

which is our final solution. What we are now left with is a component of 
software that we know can only be executed under the intended conditions and 
can guarantee producing the required results. We now move on to the next 
component and repeat the process. Step-by-step, piece-by-piece we construct 
our reliable ATC system. We did so *incrementally* through a divide-and-conquer 
strategy and by being demanding in what we expected of callers and demanding 
of ourselves in producing the correct results.

Sorry if this is a bit Mickey Mouse for some, but some may find this helpful.


[the "doing so" following means checking the validity of all calls]

:In safety-critical 
:software, how can you justify not doing so? 

If timing is so desperate that you can't use assertions, you may *have* to 
do perform this sort of analysis manually.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                           ` Don Harrison
@ 1997-07-24  0:00                             ` Jon S Anthony
  0 siblings, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-24  0:00 UTC (permalink / raw)



In article <EDswrJ.Jq1@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> :> :That's neat. Except that a postcondition will be part of the contract
> :> :(i.e. specification) for the routine, so the caller will know what to 
> :> :expect. Your code is part of the implementation.
> :> 
> :> I agree - it's belongs in a contract.
> :
> :That is trivial to provide:
> :
> :function Do_Something_Within_Time_Slice (
> :    ...
> :    Duration_Before_Abort : Our_Duration_Limits := 0.010;
> :    ...
> :    ) return Whatever_Type;
>
>  Sorry, I don't see how this acheives anything resembling the Eiffel
> contract..

Who cares about the "Eiffel contract"???  The "Eiffel contract" is no
where to be seen in this sub-discussion.  BFD to the "Eiffel
contract".  The fact is, this is a contract with the client which
describes the piece of possible behavior in question.

Actually, I don't even think you can express this sort of capability
in direct Eiffel.  So, that point is moot (yes, Robert, I know this is
an abuse of "moot" :-)

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                           ` Don Harrison
@ 1997-07-24  0:00                             ` Ken Garlington
  1997-07-29  0:00                               ` Don Harrison
  1997-07-24  0:00                             ` Don Harrison
  1 sibling, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-24  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> :So even though timing specifications with postconditions are useful, it
> :definitely is not sufficient for many HRT systems.
> 
> Agree, you also need preconditions, check-instructions and invariants.

I responded elsewhere in this thread about difficulties in trying
to accurately measure thread timings at the object level, but let
me ask you this: Have you used the technique you describe in a
production hard real-time system? Or is this just a theoretical
discussion?

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                       ` Don Harrison
@ 1997-07-24  0:00                         ` Ken Garlington
  1997-07-26  0:00                           ` Joachim Durchholz
                                             ` (2 more replies)
  0 siblings, 3 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-24  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> What we want is a way to signal to the caller that they've made a mistake and
> need to take corrective action. 

If they don't know to check that they might have made a mistake, how do
they
know what corrective action they should take?

If the erroneous code is reused in another application, doesn't it carry
its
error along with it?

What if the mistake is in your code, not the calling code?

> What about case 2)? Here, we want to check that the work we delegated was
> done properly and acheived what we set out to do. In this case, we can
> perform some checks and raise and exception against ourselves to force us
> to fix the problem (possibly by delegating)..
> 
>   procedure Assume_Control (Aircraft: Aircraft_Type) is
>   require not My_Aircraft.Mine (Aircraft)
>   begin
>     ...
>     My_Aircraft.Add (Aircraft);
>   ensure My_Aircraft.Mine (Aircraft)
>   end;
> 
> which is our final solution. What we are now left with is a component of
> software that we know can only be executed under the intended conditions and
> can guarantee producing the required results.

Assuming...

1. My_Aircraft.Mine is correct. (How is this determined? Do assertions
have
   assertions? What happens if an assertion's assertion fails, and how
is
   it distinguished from an assertion failure?)

2. Assume_Control is not called again with the same aircraft between the
   pre-condition and My_Aircraft.Add.

3. Release_Control (I propose this as the opposite of Assume_Control) is
   not called between My_Aircraft.Add and the post-condition.

4. There are no errors from other sources (e.g. extraneous code,
higher-tier
   documentation miscommunications).

Correct?

Also: If the post-condition fails, who provides the corrective action?

Also: If My_Aircraft.Add is provided by a different programmer/team than
Assume_Control, does it call My_Aircraft.Mine (or a subset thereof)? Why
or
why not?

Also: it's my understanding that DBC requires My_Aircraft.Mine be made
available
to the client of Assume_Control (no private pre-conditions). Is this the
case
here? Why or why not? Does this mean that the pre-condition may be
checked twice
before each call?

> We now move on to the next
> component and repeat the process. Step-by-step, piece-by-piece we construct
> our reliable ATC system. We did so *incrementally* through a divide-and-conquer
> strategy and by being demanding in what we expected of callers and demanding
> of ourselves in producing the correct results.

However, these results seem to be limited to making sure the code does
what
you thought it was supposed to do. How are the other failure sources
handled?

> Sorry if this is a bit Mickey Mouse for some, but some may find this helpful.
> 
> [the "doing so" following means checking the validity of all calls]
> 
> :In safety-critical
> :software, how can you justify not doing so?
> 
> If timing is so desperate that you can't use assertions, you may *have* to
> do perform this sort of analysis manually.

I think timing is part of the issue, but there are certainly other
issues.
See sections 3.1.6, 3.2.2, and 3.3 of my draft paper at:

   http://www.progsoc.uts.edu.au/~geldridg/eiffel/ariane/

Also, given that Meyer claims the "most important" effect of assertions
is manual analysis (see section 3.1 of same paper), shouldn't you be
doing this
anyway (in addition to any executable testing)? If you're not reviewing
these manually, why not?

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                         ` Ken Garlington
@ 1997-07-25  0:00                           ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-25  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:However, if this is an actor task, there is no contract (in any
:language;
:it would not be called explicitly by other parts of the application). If
:it
:is an agent or server task, the comment shown above would be associated
:in
:the task specification with the particular entry(ies) it affected.

In SCOOP, there is no concept of explicit active and passive objects. This is 
an atificial distinction which is neither necessary nor desirable (in an OO 
concurrency model). For the reasoning behind this, see "Object-oriented 
Software Construction" 2nd ed. - "Active objects" (P. 957).


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                     ` Ken Garlington
@ 1997-07-25  0:00                       ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-25  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> Ken Garlington wrote:
:> 
:> :Don Harrison wrote:
:> :>
:> :> First, part of the reason it looks complicated is that it is only emulating
:> :> (in Ada83) the real thing. As I've already said, I wouldn't implement assertions
:> :> this way if I had the proper tools to work with. If you express it in Eiffel,
:> :> it becomes simpler.
:> :
:> :OK - could you post the Ada equivalent?
:> 
:> Sure. Assuming the availability of a postcondition clause,
:> 
:>   type Input_State_Type is (.., Menu, ..);
:> 
:>   Input_State : Input_State_Type;
:>   No_of_Keys : Natural
:>   Menu_Option_Selected : Boolean;
:>   Submenu_Option_Selected : Boolean;
:> 
:>   ...
:> 
:>   function in_menu_state return Boolean is
:>   begin
:>     return (Input_State = Menu and then No_of_Keys = 0 and then
:>       not Menu_Option_Selected and then not Submenu_Option_Selected);
:>   end;
:> 
:>   procedure Interpret_CLR_Key is
:>   begin
:>     ...
:>   ensure in_menu_state                                   -- General assertion
:>   end;
:> 
:> Note that there is no precondition on Interpret_CLR_Key in accordance with the
:> fact that the Console Operator should be able to press any key at any time
:> without having the software fall over. Using assertions to validate input
:> would be a misuse of DBC.
:
:Compare this to the Ada code you presented earlier. Why is this
:significantly
:simpler or easier to read?

Due to abstraction.


:> :> Second, the compound condition represents a single higher level condition
:> :> which can be declared as a function.
:> :
:> :But doesn't that just postpone the complexity? Making the assertion
:> :nearest
:> :the point the reviewer is reading less clear, and requiring a search
:> :through
:> :other files to discover the meaning of the higher-level condition?
:> 
:> Yes, but this is no different from using encapsulation for abstraction anywhere
:> else to simplify. You aren't going to replace every call in a procedure
:> with the actual code of the called procedures (a compiler may, but a human
:> shouldn't). Neither should you do this for assertions. You don't suddenly forget
:> about abstraction just because you're writing an assertion.
:
:True, but remember that we are asking a human reader to not just
:understand what is required from a user's point of view (where
:abstraction
:permits unncessary details to be hidden), but to verify if the
:software will function correctly or not. Doesn't this imply that the
:evaluator will likely have to understand more than that required by a
:user of
:the interface?

It means they have to have to find out more but the effort involved isn't
excessive, IMO. 


:> A prerequisite for (any kind of) abstraction to be effective, of course, is
:> meaningful identifiers. If your identifier names accurately reflect what you're
:> trying to model, a high-level assertion immediately makes sense and you only
:> look further if you really need to know the details. This would be the case,
:> for example, if investigating the cause of an assertion violation or conducting
:> a manual code review. 
:
:Exactly my point. Meyer claims that such manual reviews are the primary
:benefit
:of assertions. However, abstration does not necessarily assist such a
:review; in
:fact, it may complicate it.

Well, it does add a little more work but I've never heard anyone complain 
about it.


:> Otherwise, the higher-level abstraction is not only
:> sufficient but desirable (unless you want to be needlessly swamped by compexity).
:> 
:> Using meaningful identifiers sure makes a big difference to intelligibility and,
:> IMO, is a skill that can be acquired by any reasonably literate developer
:> who is suitably encouraged (read "forced" to use them).
:
:However, if the intent is to discover errors made by the developer, to
:what
:extent can the reviewer trust those "meaningful identifiers"?

If you know that Joe Bloggs, the author, is fond of using non-indicative
identifiers, you know to check the details. Of course, *real* software 
engineers aren't like that, are they?.. Realistically, any software shop 
that *does* use Eiffel is likely to encourage/enforce sensible naming so I 
don't see it as an Earth-shattering issue. 


:> :For that matter, if this is the correct method, why not do it in Ada?
:> 
:> Purely historical reasons. If the code wasn't frozen at the moment, I probably
:> would.
:
:Then this doesn't seem to be an advantage of Eiffel over Ada, as your
:earlier comment indicated.

Perhaps we've miscommunicated here. The principle of abstracting assertions 
using functions is language-neutral - unlike a number of other assertion-related
issues.


:> :> I don't know what ADARTS is but it's one thing to be told you have to think
:> :> of all assumptions and another to demonstrate you have as evidenced by coded
:> :> assertions.
:> :
:> :Again, from a documentation standpoint, why is writing code better than
:> :documenting the assertions in a form the reviewer understands?
:> 
:> Consider the aversion of developers to documenting code. It's viewed by them
:> as a necessary burden which doesn't actually make the software work so there's
:> little motivation to do it. Executable assertions, OTOH, actually contribute
:> something (runtime checks) to a running program. Therefore, they have some
:> material value in the mind of a developer and their more likely to use them.
:
:I'm not sure I agree that well-trained and professional developers feel
:this
:way, but let's say they do. 

IME, the desire to minimise the amount of work we have to do is shared by 
everyone however well-trained and professional they happen to be. However,..


:Wouldn't this imply that they will be biased
:toward adding code that helps them get their code correct for the
:current
:use of their code (i.e. that part that provides direct value to them)
:and
:much less attention to addressing issues that don't provide value to
:them
:(e.g., handling errors due to improper reuse by "some other guy")?

Not if they take a longer-term, reuse-centred view. That sort of attitude 
would be encouraged in Eiffel shops. Those who weren't interested in practising
it would be more likely working somewhere else.


:> The by-product is that the code gets documented for free and the developers
:> actually *want* to do it.
:
:It also seems that the documentation value of the assertions will be
:lessened
:(less likely to use meaningful identifiers vs. ones that "work good
:enough").
:The line between codes that don't like to write documentation vs. coders
:that
:don't like to write self-documenting code for others to read appears to
:me
:to be easy to cross...

Yes, it is easy to cross, especially after a few nightmare experiences as 
a maintenance programmer. :)


:> :> :I also challenge whether or not you code all of the assertions you can
:> :> :envision.
:> :> :Look at your example from earlier. There's absolutely no other
:> :> :assertions you
:> :> :could consider?
:> :>
:> :> There may be others but so what? The existence of any I may not have thought
:> :> of doesn't negate the effectiveness of those I *have* thought of.
:> :
:> :But how do you draw the line between the assumptions you state and the
:> :assumptions you leave silent?
:> 
:> Sorry, not sure what you're driving at.
:
:Every error condition that might occur (e.g., adding extra code that
:makes an extraneous assignment), but is not checked by an assertion,
:would appear to be an undocumented assumption. Every undocumented
:assumption,
:per Meyer, represents an incomplete description of the interface.

True.

:How do you decide which assumptions not to document?

I can only speak for myself, but I document as many as I can think of without 
going overboard (bearing in mind I'm developing realtime software). Because 
of my domain, I'm probably more selective than a non-realtime programmer 
would be.


:> :And what does that do to the oft-said statement that Eiffel programmers
:> :put in assertions for unlikely events?
:> 
:> That's what all (or at least most) assertions are. They're catering for the
:> unlikely event that the developer has made a logic error. Most of the time
:> we write code with correct logic but occasionally we make mistakes. These
:> mistakes can often be picked up by an assertion.
:
:So, how are the likely events detected?

By this definition, the likely events correspond to correct logic so we're 
not interested in them.


:And, if the same person who made the logic error writes the assertions,
:why
:is it reasonable to expect that the assertion detects the error? Won't
:the person simply make the same mistake in logic, particularly for such
:things as missed requirements?

Perhaps sometimes, but often not. Usually, the error in logic is in a different
piece of code to the assertion. (consider my ATC example). Even if the same 
person writes both the assertion and the code that uses it, there may be an 
intervening time period, giving the developer a chance to forget their 
original reasoning. Worse still, in a team-oriented setup, it usually *isn't* 
the same person and their understanding of how the system hangs together may
differ. In my own experience, a large number of such differences can be 
exposed by assertions.  


:> :> :How about the possibility that calling one of the
:> :> :functions
:> :> :in the assertion causes NO_OF_KEYS to become non-zero, just for fun?
:> :>
:> :> As I don't write functions with side effects, I'm not sure why I would want to
:> :> do that!..
:> :
:> :More correctly stated, you don't _intend_ to write assumptions with side
:> :effects, so you _assume_ there's no need to write an assertion to
:> :confirm
:> :that you, in fact, met your intent.
:> 
:> You mean meta-assertions? Obviously, Your question in tongue-in-cheek but
:> does highlight the fact that there is practical limit beyond which you don't
:> want to go and meta-assertions are well beyond that limit. Most people want to
:> go home at the end of the day.
:
:I don't know why this is a "meta-assertion." Extraneous code is a
:category of error, just like missing code.

You were talking about assertions with side-effects and seemed to be suggesting 
a need for assertions about assertions - which would be meta-assertions. These 
would be overkill, IMO.

Getting back to your question, it can be verified statically (using a tool, 
for example) that an assertion (transitively) performs no assignments.
So, a language environment with such a tool can verify for you that all your 
assertions are free of side-effects. 


:Given that "most people want to go home at the end of the day," my point
:stands.

Best have a tool do it for you, then, instead of doing it manually.


:Which assumptions do you document? 

Those you think of.

:Which do you remain undocumented? 

Those you don't (or choose to ignore for whatever reason).

:And what theory drives the decision? Does DBC say, "this type of coding error is
:more likely than the other, so protect against it first?"

In theory, you try to document as many as you can think of without 
discrimination. However, I guess you can be more selective in practice. 
Personally, I try to anticipate the most likely causes of error and document 
those possibilities in assertions. Maybe others would like to offer their 
perpective..


:> :How do you catch software design faults in your code if you assume you
:> :made
:> :no mistakes in your code?
:> 
:> Don't follow. In writing assertions, you assume you *will* make design mistakes
:> in the code proper.
:
:Except that you deliberately exclude classes of faults, apparently,
:without any statement in the code that you did so.

Not intentionally, unless it's expedient for some reason - eg. for timing.


:> If you're talking about design faults in assertions, I've
:> already answered you previously - the code proper acts as a built-in assertion
:> validation mechanism.
:
:Think again, particularly with respect to missing code.

Maybe we're misconnecting here. I'm saying if you *do* code an assertion and 
you happen to miscode it or your initial assuption was incorrect, you will 
find out because you'll get an assertion violation under legitimate, rather `
than erroneous circumstances. You then *know* the assertion is incorrect, you 
find why, and fix it. In this way, the code proper acts as an assertion 
validation mechanism.

Obviously, if you *don't* code an assertion (for whatever reason - didn't 
recognise the assumption, decided to leave it out), the code proper isn't 
going to validate it.

Not sure whether I've covered your original question, though..


:> :> There already was one, but it would be better to also have a higher level
:> :> one for initialisation. This would aid testing in that if you fed in the
:> :> wrong profile, you could verify that the IRS will not work. It wouldn't rely
:> :> on the more obscure low-level assertion that was actually violated.
:> :>
:> :> In IRS:
:> :>
:> :>   set_operational_profile (profile: OPERATIONAL_PROFILE) is
:> :>   require profile_compatible (profile)
:> :>   do .. end
:> :
:> :This would require that the profile be stored in memory, wouldn't it?
:> :The profile is a textual/graphical description of the behavior of the
:> :environment.
:> 
:> No, it simply requires that the thing you want to make assertions about can
:> be abstracted in some way. This implies both attributes (data) and operations
:> on those attributes. If you can abstract a profile using a class (which I'm
:> sure you could), then you can make assertions about it's compatibility.
:
:Don't assertions involving the enviroment require data about the
:environment?

Ultimately, in some way. In terms of textual/graphical descriptions, if you can 
capture that information in a bunch of abstractions and capture a set of 
validity rules about it, you should then be able code an assertion which 
expresses its validity. This sort of assertion is quite high-level and 
potentially complex so would be a good candidate for an abstract assertion. 


:> :You might be able to express it as "The horizontal acceleration shall
:> :not exceed xxx..." ... and in fact, it probably would make more sense
:> :to express it exactly that way (in English!) so that it is clear at
:> :the requirements level.
:> 
:> You can do both.
:
:I'm not sure I agree with the claim that all comments can be written as
:code!

Nor would I but this one sounds like it could be. :)


:> The other examples actually aren't applicable to the efficacy of DBC as
:> they stem from errors in specification documents..
:
:WUPS!

Uh-oh. :)  Why do I get the feeling this leading somewhere?..

:DBC doesn't protect against errors in specification documents? An interesting
:statement!

Not unless there was a related specification which serves indirectly to 
validate the erroneous one. This would effectively the same as if the developer
made an error somewhere and an assertion picked it up. So, leaving it out 
doesn't necessarily mean all bets are off on picking it up.

Otherwise, it's true. Alas, assertions won't do *everything* for you. :(

:Given this, then it shouldn't be able to protect against misinterpretations
:of specification documents by a developer, either, true? 

Again, not unless there was a related specification which serves indirectly to 
validate the one misinterpreted - otherwise true.

:Or, for that matter,
:misinterpretations of any higher-tier document (e.g. a design document)?

Same deal.

:Doesn't a requirement not read equate to a requirement not written?

In practical terms, yes. (For some reason, this has a familiar ring to it :)

Watch out, here comes the punchline..

:Finally, of all of the errors in code, assuming the use of existing techniques
:(code reviews, unit test, etc.) how many are "code-only" errors vs.
:misinterpretations of higher-tier documents?

Probably greater than 50%  Why, I wonder, do you ask?..  :)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00             ` Jon S Anthony
  1997-07-24  0:00               ` Don Harrison
@ 1997-07-25  0:00               ` Alan Brain
  1997-07-25  0:00                 ` Jon S Anthony
  1 sibling, 1 reply; 255+ messages in thread
From: Alan Brain @ 1997-07-25  0:00 UTC (permalink / raw)



Jon S Anthony wrote:
> 
> In article <EDquzz.EK4@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:
> 
> > :It appears to me that the difference between Ada-95 and Eiffel is like
> > :the difference between Airbags and Seatbelts.
> >
> > I'm paranoid - I'd like an airbag (static typing etc.) *and* a seatbelt
> > (DBC etc.)!  :)
> 
> Actually, I think you have that backwards: seatbelts (typing, system
> validity, etc.) and airbag (DBC).  Just like where airbags are noted
> as being somewhat useful when used with seatbelts, but not
> particularly useful (even dangerous) without seatbelts.

Whatever. His point is that either is preferrable to having none, and
having both is better than having either. A point I am in complete
agreement with.

-- 
aebrain@dynamite.com.au     <> <>    How doth the little Crocodile
| Alan & Carmel Brain|      xxxxx       Improve his shining tail?
| Canberra Australia |  xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM
100026.2014 compuserve o OO*O^^^^O*OO o oo     oo oo     oo  
                    By pulling MAERKLIN Wagons, in 1/220 Scale
See http://www.z-world.com/graphics/z/master/8856.gif for picture






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-25  0:00               ` Alan Brain
@ 1997-07-25  0:00                 ` Jon S Anthony
  0 siblings, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-07-25  0:00 UTC (permalink / raw)



In article <33D990D1.26CD@dynamite.com.au> Alan Brain <aebrain@dynamite.com.au> writes:

> Whatever. His point is that either is preferrable to having none, and
> having both is better than having either. A point I am in complete
> agreement with.

As you say, whatever...

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178
617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                     ` Ken Garlington
@ 1997-07-25  0:00                       ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-25  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> Richie Bielak wrote:
:> 
:> :I always thought it would be nice to have postconditions of the form:
:> :
:> :       ensure
:> :               execution_time < 10 -- 10 milliseconds, let's say
:> :
:> :So an exception would be raised if the routine took too long
:> :to execute.
:> 
:> I've also been thinking along these lines since about a year ago. It sits very
:> well with DBC, IMO.
:
:This would work if there is an inherent time limit to the object's
:functionality.
:It won't work if the issue is the contribution to the object to a thread
:of
:execution, particularly if the object is going to support multiple
:threads. 
:The issue of specifying absolute time in an environment where objects are
:reused
:in future applications is also a sticking point. ADARTS does thread
:timeline
:analysis independently of object interface specification, which in my
:experience makes more sense.

Actually, after reading more about SCOOP, I think you would probably use 
a different approach to implementing timed actions. You can acheive thread
based timing using predefined library classes. See the discussion of class 
TIMED in "Object-oriented Software Construction" 2nd ed. - "A watchdog 
mechanism" (P. 1019)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-23  0:00                       ` Ken Garlington
@ 1997-07-25  0:00                         ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-25  0:00 UTC (permalink / raw)



All of the following issues become irrelevant in the context of library classes
that allow thread-based timing. See my previous post about class TIMED.


Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> Ken Garlington wrote:
:> 
:> :Richie Bielak wrote:
:> 
:> :> I always thought it would be nice to have postconditions of the form:
:> :>
:> :>         ensure
:> :>                 execution_time < 10 -- 10 milliseconds, let's say
:>            end
:>            ^^^
:>            my addition
:> :>
:> :> So an exception would be raised if the routine took too long
:> :> to execute.
:> :
:> :Of course, you have to decide if "execution time" includes the time for
:> :the postcondition (including any code that executes after the actual
:> :test instruction)!
:> 
:> It would be the duration when the expression "execution_time" is evaluated.
:> There would be no statements following the assertion so it should be accurate
:> enough for most purposes. 
:
:1. Why would there be no statements afterwards?
:2. If there were assertions _before_ this one, would their time be
:included?
:3. How is the assumption "accurate enough" captured in an Eiffel
:assertion? (_Would_
:it be captured?)
:
:> If not, you can apply a small compensating adjustment
:> to the relational expression:
:> 
:>          ensure
:>                  execution_time < 9.99  -- milliseconds
:>          end
:
:However, this compensation depends upon making assumptions of the
:time it takes to do the assertions... and we want to avoid writing code
:whose correctness depends upon assumptions about how fast the code runs,
:right?
:
:> 
:> :We usually have such measurements _outside_ the code sequence being
:> :measured (i.e., in the scheduler).
:> 
:> ..in which case, you'd presumably be subject to the timing inaccuracies of
:> the scheduler, anyway.
:
:But the timing inaccuracies of the scheduler are at the thread level.
:Your
:inaccuracies are at the object level. If a lot of objects are called in
:the course of a thread's execution (or a few are called a lot of times),
:your inaccuracies build. Mine don't (particularly if the start of the
:thread is controlled by a high-accuracy timer/low-overhead interrupt
:handler, which is typical for hard real-time systems).
:
:> 
:> Don.
:> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
:> Don Harrison             donh@syd.csa.com.au



-- 
Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                 ` Paul M Gover
@ 1997-07-26  0:00                   ` Joachim Durchholz
  1997-07-28  0:00                     ` Robert S. White
  1997-07-29  0:00                     ` Don Harrison
  0 siblings, 2 replies; 255+ messages in thread
From: Joachim Durchholz @ 1997-07-26  0:00 UTC (permalink / raw)



Paul M Gover wrote:
> 
> Joachim Durchholz wrote:
> > Now *that* sounds bogus to me. The code should execute in exactly
> > the
> > same way, wether assertions are turned on or off. If you don't have
> > enough confidence in the compiler to generate code that runs
> > correctly,
> > why do you use a compiler at all?
> By definition, the code executes differently depending on whether
> asserions
> are turned on or off - because the assertion checking _is_ code!

That's not what assertions are supposed to do. Of course assertions may
themselves be buggy, but the only possibility here should be that an
assertion signals an error where there is none.

> In particular, there's likely to be some memory management going on in
> an
> OO system.  Two possibilities: we could run out of memory in the
> assertion,
> or the memory management might take too long for some critical signal.

Plus the assertion themselves will take time to check, which influences
timing.
I'm not in the hard real-time business (and have never been), so I might
be grossly off the mark. What I currently think is that no harm should
result if the code runs faster after disabling assertion checking. (Some
informed people in this group have claimed otherwise, but I haven't seen
convincing arguments why this should be the case.)

Checking assertions (in the Eiffel sense) must not have observable
effects, except that the program may run slower (or similar irrelevant
differences). There are some style guidelines and hard rules that
enforce this.
Of course the mechanism for reporting exceptions may interfere with the
normal functioning of the user interface. (You can take the "exceptions
don't affect execution" only so far.)

> I currently support a program where switching the diagnostic trace on
> breaks part of the user interface (since the program's correct,
> I don't need to trace, so I don't need to fix the bug!?!).

This depends. Is the diagnostic a debugging aid? Then you don't really
have to fix it (at least if you are confident that everything will work
in the absence of diagnostics).
If the diagnostics are part of the finished product, you'll have to fix
it, of course. But then this is not what assertions are intended for (in
Eiffel). The possibility to switch off assertion checking without
affecting the program's semantics is an *axiom* in Eiffel; the language
and the guidelines go to great lengths to achieve this.

Regards,
Joachim
-- 
Please don't send unsolicited ads.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                         ` Ken Garlington
@ 1997-07-26  0:00                           ` Joachim Durchholz
  1997-07-31  0:00                             ` Ken Garlington
  1997-07-28  0:00                           ` Nick Leaton
  1997-07-29  0:00                           ` Don Harrison
  2 siblings, 1 reply; 255+ messages in thread
From: Joachim Durchholz @ 1997-07-26  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> What if the mistake is in your code, not the calling code?

There's always an end to the chain in buck-passing. If the mistake is in
our code, we obviously have to fix it. DBC is not a silver bullet, it is
just a way of unambiguously distributing responsibilities (preconditions
to the caller, postconditions to the callee - and the callee is *not*
required to check its preconditions in its code).
Or, if the system must be fail-safe, the buck is passed up to some
routine that just takes note of the software failure and tries something
else (or detonates the rocked).

> 1. My_Aircraft.Mine is correct. (How is this determined?

Proofreading.
However, assertions are (hopefully) on a higher level than the program
code, so the task of the proofreader becomes easier by that level.

>    Do assertions
>    have
>    assertions?

In Eiffel, no. Assertions are on a higher level of reasoning than the
program code itself. The advice is to write simple assertions (again to
make proofreading easier).
Personally, I'm not totally sure wether this will properly scale up to
arbitrarily large systems. Adding assertions to assertions, however,
adds a second layer of checking (which would have to be read and
understood by the proofreader), so assertions on assertions aren't too
useful anyway.

> 2. Assume_Control is not called again with the same aircraft between
>    the
>    pre-condition and My_Aircraft.Add.
> 3. Release_Control (I propose this as the opposite of Assume_Control)
>    is
>    not called between My_Aircraft.Add and the post-condition.

This is taken care of.
For single-threaded applications, the problem cannot arise anyway.
For multi-threading, only a single procedure may execute at any time for
a given object.

> 4. There are no errors from other sources (e.g. extraneous code,
>    higher-tier
>    documentation miscommunications).

You might formalize the higher-tier documentation as deferred (abstract)
Eiffel classes. The concrete system is built by deriving from the
deferred classes. DBC makes sure that the concrete classes will abide by
the contracts in the high-level specification classes.
Of course this does not preclude other communication problems. But
there's no silver bullet for this.

> Also: If the post-condition fails, who provides the corrective action?

A postcondition failure means the routine is wrong; as it already has
terminated executing, it cannot take corrective action.
So the caller is left to deal with the broken contract - either by
failing its own contract (the default reaction), or by taking corrective
action (catching the exception and trying some other approach).

> Also: If My_Aircraft.Add is provided by a different programmer/team
> than
> Assume_Control, does it call My_Aircraft.Mine (or a subset thereof)?
> Why
> or
> why not?

I'm having trouble understanding the situation you're thinking of here.
Usually a class is written by a single programmer/team.
Besides, wether a routine is called once or twice doesn't seem related
to who wrote it, so I'm rather confused here...

> Also: it's my understanding that DBC requires My_Aircraft.Mine be made
> available
> to the client of Assume_Control (no private pre-conditions). Is this
> the
> case
> here?

Yes.

> Why or why not?

The caller must be able to check wether it has fulfilled all
preconditions. It can do so only if all features used in preconditions
are available to him.

> Does this mean that the pre-condition may be
> checked twice
> before each call?

Yes. (Only once with precondition checking turned off.)
However, this is misleading. If PBC is in place, you don't have to write

  do_something (My_Aircraft: AIRCRAFT) is
  do
    if MyAircraft.Mine then
      -- do something with My_Aircraft
    else
      -- declare error
    end;
  end; -- do_something

Instead, you write

  do_something (My_Aircraft: AIRCRAFT) is
  require My_Aircraft.Mine
  do
    -- do something with My_Aircraft
  end; -- do_something

which is shorter, and clearly separates the "defensive programming" part
from the really useful code.

> However, these results seem to be limited to making sure the code does
> what
> you thought it was supposed to do.
> How are the other failure sources
> handled?
> ...
> Also, given that Meyer claims the "most important" effect of
> assertions
> is manual analysis (see section 3.1 of same paper), shouldn't you be
> doing this
> anyway (in addition to any executable testing)? If you're not
> reviewing
> these manually, why not?

DBC doesn't handle external failure sources. It is there to make sure
that the code does what it's supposed to do.
As a very useful side effect, it also seduces the programmer into
getting a clear picture of what the routine is actually supposed to do
(something many programmers really need).

Regards,
Joachim
-- 
Please don't send unsolicited ads.






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-26  0:00                   ` Joachim Durchholz
@ 1997-07-28  0:00                     ` Robert S. White
  1997-08-09  0:00                       ` Marinos J. Yannikos
  1997-07-29  0:00                     ` Don Harrison
  1 sibling, 1 reply; 255+ messages in thread
From: Robert S. White @ 1997-07-28  0:00 UTC (permalink / raw)



In article <33D9B8F9.4693018C@munich.netsurf.de>, 
joachim.durchholz@munich.netsurf.de says...

>Plus the assertion themselves will take time to check, which influences
>timing.
>I'm not in the hard real-time business (and have never been), so I might
>be grossly off the mark. What I currently think is that no harm should
>result if the code runs faster after disabling assertion checking. (Some
>informed people in this group have claimed otherwise, but I haven't seen
>convincing arguments why this should be the case.)

  I hope you never have to do safety-critical hard real-time programming
with more than a very few tasks running.  You have never hear of a 
deadlock?  Race condition?  Sure you try to design to avoid such things,
but you can never be sure that you have really successsfully avoided
all timing sensitivities until you _test_ for them!  The cold HARD rule
is that if the machine code changes, then regression tests _must_ be 
done.

>
>Checking assertions (in the Eiffel sense) must not have observable
>effects, except that the program may run slower (or similar irrelevant
>differences). There are some style guidelines and hard rules that
>enforce this.

  Not a suitable guard for hard real-time!  Just what is the protection
mechanism for this "must not"?  Who validates Eiffel compiler object 
code to not have any "observable effect" when release code turns off
assertion checks?

>The possibility to switch off assertion checking without
>affecting the program's semantics is an *axiom* in Eiffel; the language
>and the guidelines go to great lengths to achieve this.

  But it has not convinced me that it (assertions one during 
development, off later for the released version) are suitable for 
hard real-time without doing a set of regression tests that would expose
timing sensistivity problems.  The FAA with DO-178B would be very unhappy
that all of the object code paths are not thoroughly tested in the final
released code version.
_____________________________________________________________________
Robert S. White         -- An embedded systems software engineer





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                         ` Ken Garlington
  1997-07-26  0:00                           ` Joachim Durchholz
@ 1997-07-28  0:00                           ` Nick Leaton
  1997-07-28  0:00                             ` Steve Jones - JON
  1997-07-31  0:00                             ` Ken Garlington
  1997-07-29  0:00                           ` Don Harrison
  2 siblings, 2 replies; 255+ messages in thread
From: Nick Leaton @ 1997-07-28  0:00 UTC (permalink / raw)



Ken Garlington wrote:

Lots of critisms about Don Harrisons ATC example.

OK Ken, You write a requirement document for Don's example and I'm sure
someone will code it up in Eiffel. Just a simple set of requirements
will do. 

PS In the UK the ATC are still using Jovial.

-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-28  0:00                           ` Nick Leaton
@ 1997-07-28  0:00                             ` Steve Jones - JON
  1997-07-31  0:00                             ` Ken Garlington
  1 sibling, 0 replies; 255+ messages in thread
From: Steve Jones - JON @ 1997-07-28  0:00 UTC (permalink / raw)



Nick Leaton <nickle@calfp.co.uk> writes:

[snip]
> PS In the UK the ATC are still using Jovial.

The new centre (NERC) is a majority Ada product, when it comes on line
however....

-- 
|---------------- C++ is to OO what C is to structured --------------------|
|----The above opinions rarely reflect my own and never my employers'------|
|Do not add me to mailing lists violations will be billed for time.        |




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-26  0:00                   ` Joachim Durchholz
  1997-07-28  0:00                     ` Robert S. White
@ 1997-07-29  0:00                     ` Don Harrison
  1 sibling, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-29  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:

:Paul M Gover wrote:
:> 
:> Joachim Durchholz wrote:
:> > Now *that* sounds bogus to me. The code should execute in exactly
:> > the
:> > same way, wether assertions are turned on or off. If you don't have
:> > enough confidence in the compiler to generate code that runs
:> > correctly,
:> > why do you use a compiler at all?
:> By definition, the code executes differently depending on whether
:> asserions
:> are turned on or off - because the assertion checking _is_ code!
:
:That's not what assertions are supposed to do. Of course assertions may
:themselves be buggy, but the only possibility here should be that an
:assertion signals an error where there is none.

Since any software (sequential or concurrent) can contain timing-triggered 
branches, it's not only possible but probable that it will behave differently 
depending on whether assertions are turned on or off. Concurrent software 
typically contains such branches which may affect behaviour when extra 
processing overheads (for example, GC, assertions) are applied. Additionally, 
the non-determinism of these overheads may worsen this effect. 

This different behaviour does not indicate an error. However, another 
consequence of that overhead, which *is* erroneous, is that the software may 
fail to meet its specified timing constraints. This is the fundamental problem 
of using GC and assertions in timing critical contexts with current technology. 

Perhaps these barriers can be overcome by using more sophisticated technology..


:> In particular, there's likely to be some memory management going on in
:> an
:> OO system.  Two possibilities: we could run out of memory in the
:> assertion,
:> or the memory management might take too long for some critical signal.
:
:Plus the assertion themselves will take time to check, which influences
:timing.
:I'm not in the hard real-time business (and have never been), so I might
:be grossly off the mark. What I currently think is that no harm should
:result if the code runs faster after disabling assertion checking. (Some
:informed people in this group have claimed otherwise, but I haven't seen
:convincing arguments why this should be the case.)

As you say, the different behaviour is not a problem. However, the failure 
to meet timing constraints is.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-29  0:00                                 ` Ron Kohl
@ 1997-07-29  0:00                                   ` Don Harrison
  1997-07-30  0:00                                     ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-29  0:00 UTC (permalink / raw)



Ron Kohl wrote:

:Don Harrison wrote:
:> 
:> Ken Garlington wrote:
:> 
:> :I responded elsewhere in this thread about difficulties in trying
:> :to accurately measure thread timings at the object level,
:> 
:> As I've already explained, SCOOP *does* support thread-level timing. The fact
:> this has not yet been tested in a realtime system doesn't invalidate any
:> logical arguments made about it.
:> 
:  Ken's point is still valid.  

Yes, sorry - I was a bit blunt. I agree with Ken's statement. Unless an 
object corresponds directly with a thread, it isn't possible to measure thread 
timings at the object level.
 
:If a 'system feature' (in this case
:SCOOP's thread-level timing capability) is claimed to support hard
:real-time and then this feature is implemented into a hard real-time
:system and does not perform according to it's advertisement, then the
:empirical data has provided a counter-example to the claims about that
:feature.  The point being that empirical data can either provide
:examples to support theoretical claims/conjectures or it can totally
:invalidate such claims if it can produce a single, valid counter
:example.

Absolutely! Empirical data can *disprove* a theory but not prove it. A single 
contrary observation is sufficient to disprove a theory whereas any number of
supportive observations cannot prove it.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                         ` Ken Garlington
  1997-07-26  0:00                           ` Joachim Durchholz
  1997-07-28  0:00                           ` Nick Leaton
@ 1997-07-29  0:00                           ` Don Harrison
  1997-07-31  0:00                             ` Ken Garlington
  2 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-07-29  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> What we want is a way to signal to the caller that they've made a mistake and
:> need to take corrective action. 
:
:If they don't know to check that they might have made a mistake, 

They *do* know because they get an exception.

:how do they know what corrective action they should take?

To determine the right corrective action, they determine which specific 
(sub-)expression triggered the violation and work out the cause by conventional
means, namely logical deduction.

:If the erroneous code is reused in another application, doesn't it carry
:its error along with it?

Yes, that's why it's important to fix it. :)

:What if the mistake is in your code, not the calling code?

The context we're dicussing is a precondition, so I assume you mean a mistake 
in the precondition. This will be obvious from the fact that the call is valid. 
This is what I mean about the code proper validating assertions. (See my previous 
posts for details).


:> What about case 2)? Here, we want to check that the work we delegated was
:> done properly and acheived what we set out to do. In this case, we can
:> perform some checks and raise and exception against ourselves to force us
:> to fix the problem (possibly by delegating)..
:> 
:>   procedure Assume_Control (Aircraft: Aircraft_Type) is
:>   require not My_Aircraft.Mine (Aircraft)
:>   begin
:>     ...
:>     My_Aircraft.Add (Aircraft);
:>   ensure My_Aircraft.Mine (Aircraft)
:>   end;
:> 
:> which is our final solution. What we are now left with is a component of
:> software that we know can only be executed under the intended conditions and
:> can guarantee producing the required results.
:
:Assuming...
:
:1. My_Aircraft.Mine is correct. (How is this determined? 

Joachim has already mentioned code inspection. 

Also, if Mine is called anywhere in the code proper of the system and it has 
its own assertions, it will be validated by them. However, these lower-level 
assertions won't be evaluated as part of higher-level assertion evaluation.

(For details, see OOSC-2, Chapter 11 - "Design by Contract: Building Reliable
Software", Page 400 ff.)

In this sense, I suppose you could say there are "assertions about assertions" (meta-assertions). They help where they're needed most - where assertions are 
abstracted using boolean functions.

:Do assertions have assertions? 

See above.

:What happens if an assertion's assertion fails, and how
:is
:   it distinguished from an assertion failure?)

Because assertion checking is turned off during assertion evaluation, this
doesn't happen.

:2. Assume_Control is not called again with the same aircraft between the
:   pre-condition and My_Aircraft.Add.
:
:3. Release_Control (I propose this as the opposite of Assume_Control) is
:   not called between My_Aircraft.Add and the post-condition.

Neither of these concurrency issues exist under SCOOP because the runtime system 
automatically locks objects on behalf of the thread using them. It's simply 
impossible to have concurrent access to an object by multiple threads. 

(For details of object locking under SCOOP, see OOSC-2, Section 30.6 - 
"Accessing separate objects", Page 982 ff.)

Ada, in contrast, does allow this - for example, if tasking is used in isolation. 
To overcome this deficiency, you have to either roll-your-own object protection
(using semaphores, for example) or use protected objects. Using Ada protected 
objects is fine, but they lack the flexibility of Eiffel separate objects.

:4. There are no errors from other sources (e.g. extraneous code,
:higher-tier
:   documentation miscommunications).

I've already covered the case of extraneous code in a previous post. 

WRT documentation-related problems, these are outside the scope of any runtime 
error checking mechanism. DBC is *almost* a silver bullet but not quite. :)

:Correct?

All of these issues are either non-issues or already catered for.


:Also: If the post-condition fails, who provides the corrective action?

During development, you, the designer of the code (or your delegate) by fixing 
the problem. Additionally, in the case of critical software, you can add a
rescue clause (exception handler) to keep the show on the road in production. 

:Also: If My_Aircraft.Add is provided by a different programmer/team than
:Assume_Control, does it call My_Aircraft.Mine (or a subset thereof)? 

It doesn't matter. What's your point?..

:Also: it's my understanding that DBC requires My_Aircraft.Mine be made
:available
:to the client of Assume_Control (no private pre-conditions). Is this the
:case
:here? Why or why not? Does this mean that the pre-condition may be
:checked twice
:before each call?

(Joachim's already answered this).


:> We now move on to the next
:> component and repeat the process. Step-by-step, piece-by-piece we construct
:> our reliable ATC system. We did so *incrementally* through a divide-and-conquer
:> strategy and by being demanding in what we expected of callers and demanding
:> of ourselves in producing the correct results.
:
:However, these results seem to be limited to making sure the code does what
:you thought it was supposed to do. 

Yes?..

:How are the other failure sources handled?

Clairvoyance. :)  Seriously, we already know that DBC can't identify all sources
of error. Other classes of error may be identified through other means that 
you're already well acquanted with.

:> Sorry if this is a bit Mickey Mouse for some, but some may find this helpful.


:Also, given that Meyer claims the "most important" effect of assertions
:is manual analysis (see section 3.1 of same paper), shouldn't you be
:doing this anyway (in addition to any executable testing)? 

Absolutely! For critical application, you want to do whatever you can to 
improve reliability - including manual analysis.

:If you're not reviewing these manually, why not?

I would.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-24  0:00                             ` Ken Garlington
@ 1997-07-29  0:00                               ` Don Harrison
  1997-07-29  0:00                                 ` Ron Kohl
  1997-07-31  0:00                                 ` Ken Garlington
  0 siblings, 2 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-29  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:I responded elsewhere in this thread about difficulties in trying
:to accurately measure thread timings at the object level, 

As I've already explained, SCOOP *does* support thread-level timing. The fact 
this has not yet been tested in a realtime system doesn't invalidate any 
logical arguments made about it. 


Empirical evidence doesn't *prove* anything. It merely adds credibility to 
theoretical arguments. We believe that General Relativity is valid because 
empirical evidence backs it up. But arguments made about its effects 
(gravitational lenses, behaviour of clocks etc.) were valid even *before* they 
were observed empirically. Observing these phenomena merely helps us to 
*believe* that it's a valid model of reality.

A good example of how empirical observation proves nothing is found in the 
breakdown of Classical Physics. It was thought to be a valid physical model
because empirical observations backed it up. The fact that those observations 
didn't *prove* its validity can be seen by its failure to explain *other* 
subsequent empirical observations - namely those concerning objects with high 
relative velocities. These observations conflicted with the theoretical model 
and led to Einstein's formulation of Special Relativity. Even though Special 
Relativity has been observed to be a better physical model, it can never be 
*proven* by those observations.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-29  0:00                               ` Don Harrison
@ 1997-07-29  0:00                                 ` Ron Kohl
  1997-07-29  0:00                                   ` Don Harrison
  1997-07-31  0:00                                 ` Ken Garlington
  1 sibling, 1 reply; 255+ messages in thread
From: Ron Kohl @ 1997-07-29  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :I responded elsewhere in this thread about difficulties in trying
> :to accurately measure thread timings at the object level,
> 
> As I've already explained, SCOOP *does* support thread-level timing. The fact
> this has not yet been tested in a realtime system doesn't invalidate any
> logical arguments made about it.
> 
  Ken's point is still valid.  If a 'system feature' (in this case
SCOOP's thread-level timing capability) is claimed to support hard
real-time and then this feature is implemented into a hard real-time
system and does not perform according to it's advertisement, then the
empirical data has provided a counter-example to the claims about that
feature.  The point being that empirical data can either provide
examples to support theoretical claims/conjectures or it can totally
invalidate such claims if it can produce a single, valid counter
example.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-29  0:00                                   ` Don Harrison
@ 1997-07-30  0:00                                     ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-07-30  0:00 UTC (permalink / raw)



Let's try this again..

Ron Kohl wrote:

:Don Harrison wrote:
:> 
:> Ken Garlington wrote:
:> 
:> :I responded elsewhere in this thread about difficulties in trying
:> :to accurately measure thread timings at the object level,
:> 
:> As I've already explained, SCOOP *does* support thread-level timing. The fact
:> this has not yet been tested in a realtime system doesn't invalidate any
:> logical arguments made about it.
:> 
:  Ken's point is still valid.  

Yes, sorry - I was a bit blunt. I agree with Ken's statement. Unless an 
object corresponds directly with a thread, it isn't possible to measure thread 
timings at the object level.
 
:If a 'system feature' (in this case
:SCOOP's thread-level timing capability) is claimed to support hard
:real-time and then this feature is implemented into a hard real-time
:system and does not perform according to it's advertisement, then the
:empirical data has provided a counter-example to the claims about that
:feature.  The point being that empirical data can either provide
:examples to support theoretical claims/conjectures or it can totally
:invalidate such claims if it can produce a single, valid counter
:example.

Absolutely! Empirical data can *disprove* a theory but not prove it. A single 
correctly-interpreted contrary observation is sufficient to disprove a theory 
whereas any number of supportive observations cannot prove it. Obviously, any 
number of incorrectly-interpreted contrary observations can never disprove a 
theory.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au





-- 
Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-26  0:00                           ` Joachim Durchholz
@ 1997-07-31  0:00                             ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-31  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:
> 
> Ken Garlington wrote:
> > What if the mistake is in your code, not the calling code?
> 
> There's always an end to the chain in buck-passing. If the mistake is in
> our code, we obviously have to fix it. DBC is not a silver bullet, it is
> just a way of unambiguously distributing responsibilities (preconditions
> to the caller, postconditions to the callee - and the callee is *not*
> required to check its preconditions in its code).
> Or, if the system must be fail-safe, the buck is passed up to some
> routine that just takes note of the software failure and tries something
> else (or detonates the rocked).

Or shuts down?

My read of the Meyer paper is that DBC is designed to avoid
buck-passing:
that each routine is essentially bullet-proof internally. However, if
the
group "distributing the responsibilities" is also the group whose errors
you are trying to detect, how does this help?

> 
> > 1. My_Aircraft.Mine is correct. (How is this determined?
> 
> Proofreading.
> However, assertions are (hopefully) on a higher level than the program
> code, so the task of the proofreader becomes easier by that level.

Why would they be expected to be at a "higher level?" Take the example
in the Ariane 5 paper. It doesn't appear to have any particular
abstration associated with it.

Consider also the limits of proofreading described in my draft paper.
Furthermore, how does DBC make proofreading any easier than without?

> 
> >    Do assertions
> >    have
> >    assertions?
> 
> In Eiffel, no. Assertions are on a higher level of reasoning than the
> program code itself. The advice is to write simple assertions (again to
> make proofreading easier).

But writing simple assertions to make it easier to review also implies
only writing critical assertions to reduce the workload, doesn't it?
And if the wrong critical assertions are chosen, then more errors
are likely.

> Personally, I'm not totally sure wether this will properly scale up to
> arbitrarily large systems. Adding assertions to assertions, however,
> adds a second layer of checking (which would have to be read and
> understood by the proofreader), so assertions on assertions aren't too
> useful anyway.
> 
> > 2. Assume_Control is not called again with the same aircraft between
> >    the
> >    pre-condition and My_Aircraft.Add.
> > 3. Release_Control (I propose this as the opposite of Assume_Control)
> >    is
> >    not called between My_Aircraft.Add and the post-condition.
> 
> This is taken care of.
> For single-threaded applications, the problem cannot arise anyway.
> For multi-threading, only a single procedure may execute at any time for
> a given object.

So, in a real-time system, no interrupts can occur while a procedure is
executing? How is this managed, particularly for non-maskable
interrupts?
Assuming it is managed, how can latency be managed in such a system?
Is the nulti-threading rule part of the Eiffel spec, or part of an
implementation?

> 
> > 4. There are no errors from other sources (e.g. extraneous code,
> >    higher-tier
> >    documentation miscommunications).
> 
> You might formalize the higher-tier documentation as deferred (abstract)
> Eiffel classes. 

You might.. if (a) the requirements writer knows Eiffel, (b) all readers
know Eiffel, (c) Eiffel has been shown as a useful language for
requirements analysis (compare and contrast with tools such as
StateMate,
for example).

> The concrete system is built by deriving from the
> deferred classes. DBC makes sure that the concrete classes will abide by
> the contracts in the high-level specification classes.
> Of course this does not preclude other communication problems. But
> there's no silver bullet for this.
> 
> > Also: If the post-condition fails, who provides the corrective action?
> 
> A postcondition failure means the routine is wrong; as it already has
> terminated executing, it cannot take corrective action.
> So the caller is left to deal with the broken contract - either by
> failing its own contract (the default reaction), or by taking corrective
> action (catching the exception and trying some other approach).

Wouldn't that cause the very Ariane 5 failure that DBC was supposed to
prevent?

> 
> > Also: If My_Aircraft.Add is provided by a different programmer/team
> > than
> > Assume_Control, does it call My_Aircraft.Mine (or a subset thereof)?
> > Why
> > or
> > why not?
> 
> I'm having trouble understanding the situation you're thinking of here.
> Usually a class is written by a single programmer/team.

Really? Doesn't sound like these routines get reused or maintained over
time!

> Besides, wether a routine is called once or twice doesn't seem related
> to who wrote it, so I'm rather confused here...

If different people/teams are each writing a separate piece of code
that has an interface between them, then any of the following can
happen:

1. One team checks the assertions associated with the interface (e.g.
the preconditions are checked by the callee).

2. Both teams do the check, not knowing that the other team is also
doing it
(or perhaps not caring, if they want their code to be separately
reusable.)
After all, the callee does make the preconditions available to the
caller
(see below), so why wouldn't they both end up doing the check (and
adding
the time to the system).

3. Each team assumes the other team does the check, and neither does it.

> > Also: it's my understanding that DBC requires My_Aircraft.Mine be made
> > available
> > to the client of Assume_Control (no private pre-conditions). Is this
> > the
> > case
> > here?
> 
> Yes.
> 
> > Why or why not?
> 
> The caller must be able to check wether it has fulfilled all
> preconditions. It can do so only if all features used in preconditions
> are available to him.
> 
> > Does this mean that the pre-condition may be
> > checked twice
> > before each call?
> 
> Yes. (Only once with precondition checking turned off.)
> However, this is misleading. If PBC is in place, you don't have to write
> 
>   do_something (My_Aircraft: AIRCRAFT) is
>   do
>     if MyAircraft.Mine then
>       -- do something with My_Aircraft
>     else
>       -- declare error
>     end;
>   end; -- do_something
> 
> Instead, you write
> 
>   do_something (My_Aircraft: AIRCRAFT) is
>   require My_Aircraft.Mine
>   do
>     -- do something with My_Aircraft
>   end; -- do_something
> 
> which is shorter, and clearly separates the "defensive programming" part
> from the really useful code.

Not the issue. The caller of do_something (potentially) calls
My_Aircraft.Mine, which
then calls My_Aircraft.Mine again. This doesn't seem like a particularly
efficient
way to manage assertions!

> 
> > However, these results seem to be limited to making sure the code does
> > what
> > you thought it was supposed to do.
> > How are the other failure sources
> > handled?
> > ...
> > Also, given that Meyer claims the "most important" effect of
> > assertions
> > is manual analysis (see section 3.1 of same paper), shouldn't you be
> > doing this
> > anyway (in addition to any executable testing)? If you're not
> > reviewing
> > these manually, why not?
> 
> DBC doesn't handle external failure sources.

How can this be, if you are "unambiguously distributing responsibilities
(preconditions to the caller...". Isn't the caller an "external failure
source"?

> It is there to make sure
> that the code does what it's supposed to do.
> As a very useful side effect, it also seduces the programmer into
> getting a clear picture of what the routine is actually supposed to do
> (something many programmers really need).

I would be much more convinced of this if there was a study that
demonstrated it. As you note above, excessive assertions can obfuscate
as well as clarify, and many Eiffel advocates seem to believe that
the more assertions, the better. Isn't this a self-defeating system?

> 
> Regards,
> Joachim
> --
> Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-28  0:00                           ` Nick Leaton
  1997-07-28  0:00                             ` Steve Jones - JON
@ 1997-07-31  0:00                             ` Ken Garlington
  1 sibling, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-07-31  0:00 UTC (permalink / raw)



Nick Leaton wrote:
> 
> Ken Garlington wrote:
> 
> Lots of critisms about Don Harrisons ATC example.
> 
> OK Ken, You write a requirement document for Don's example and I'm sure
> someone will code it up in Eiffel. Just a simple set of requirements
> will do.

See the ATC system requirements set in the ADARTS Guidebook, vol. 2.
(ATC is one of the example systems used to teach ADARTS). It's
reasonably
small, and chock-full of those tricky system timing issues that appear
to be trouble in Eiffel. (See, I can reuse requirements! :)

For more information, see http://www.software.org.

> 
> PS In the UK the ATC are still using Jovial.

So are we, on the F-16. A reasonably good language for such systems
(although
I like Ada better).

> 
> --
> 
> Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-29  0:00                               ` Don Harrison
  1997-07-29  0:00                                 ` Ron Kohl
@ 1997-07-31  0:00                                 ` Ken Garlington
  1997-08-07  0:00                                   ` Don Harrison
  1 sibling, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-31  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :I responded elsewhere in this thread about difficulties in trying
> :to accurately measure thread timings at the object level,
> 
> As I've already explained, SCOOP *does* support thread-level timing. The fact
> this has not yet been tested in a realtime system doesn't invalidate any
> logical arguments made about it.

No, but then again, saying "X *does* support thread-level timing" isn't
a
logical argument, it's an assertion. And assertions, in the absence of
any experience (either general experience from the author, or specific
experience with X in a real system) are not particularly useful.

Futhermore, here is a counter-argument to writing timing assertions
at the object level:

Using letters to denote objects, let's build a thread. The notation
x{object}y means that the object is executed between x and y times.
The arrows indicate that one object is executed before another object
in the sequence. (For simplicity, we'll neglect objects calling
objects).

Thread: A -> B -> 1{C}4 -> D

The max time for this thread is: A + B + 4*C + D, right?

No!

It also includes:
 1. the entry/exit code for each object (4 times that, for C),
 2. the time to start and stop the thread itself
 3. Any time between object invocations "stolen" by other threads.

If you start the measurement before the call to A, and stop it
after the call to D, you only have to worry about #2 above
(which is usually fixed). If you do the measurement at the object
level, all three will skew your results. What's worse, #1's
effect increases with the number of objects/calls to objects in
the thread. As a result, it's not a particularly useful approach
when dealing with thread timings (as opposed to object timings).
(This IS backed up by empirical evidence, by the way!)




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-29  0:00                           ` Don Harrison
@ 1997-07-31  0:00                             ` Ken Garlington
  1997-08-07  0:00                               ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-07-31  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :Don Harrison wrote:
> :>
> :> What we want is a way to signal to the caller that they've made a mistake and
> :> need to take corrective action.
> :
> :If they don't know to check that they might have made a mistake,
> 
> They *do* know because they get an exception.

Not when they're _writing_ the code, unfortunately. Remember, the
assumption is
that the caller (directly or indirectly) made a mistake to cause the
exception
in the first place. However, in your scheme, you're trusting them to
take the
right corrective action to a problem that they may have unintentionally
caused
in the first place!

Human lapses in judgement aren't usually confined to a few-second
bursts. If
they make an invalid assumption in their algorithm, they're probably
going to
maintain that same invalid assumption when writing their
exception-handling
code.

> 
> :how do they know what corrective action they should take?
> 
> To determine the right corrective action, they determine which specific
> (sub-)expression triggered the violation and work out the cause by conventional
> means, namely logical deduction.

This brings up the second point. Why would a methodology/language go to
great lengths to _detect_ errors, but completely punt ("use conventional
means") to determine what to do _afterwards_?

> :If the erroneous code is reused in another application, doesn't it carry
> :its error along with it?
> 
> Yes, that's why it's important to fix it. :)

Doesn't this erode the argument of using Eiffel to support reuse, if
errors
are so easily ported between applications?

> 
> :What if the mistake is in your code, not the calling code?
> 
> The context we're dicussing is a precondition, so I assume you mean a mistake
> in the precondition.  This will be obvious from the fact that the call is valid.

Your code thinks the call is invalid. Who decides otherwise?

> This is what I mean about the code proper validating assertions. (See my previous
> posts for details).
> 
> :> What about case 2)? Here, we want to check that the work we delegated was
> :> done properly and acheived what we set out to do. In this case, we can
> :> perform some checks and raise and exception against ourselves to force us
> :> to fix the problem (possibly by delegating)..
> :>
> :>   procedure Assume_Control (Aircraft: Aircraft_Type) is
> :>   require not My_Aircraft.Mine (Aircraft)
> :>   begin
> :>     ...
> :>     My_Aircraft.Add (Aircraft);
> :>   ensure My_Aircraft.Mine (Aircraft)
> :>   end;
> :>
> :> which is our final solution. What we are now left with is a component of
> :> software that we know can only be executed under the intended conditions and
> :> can guarantee producing the required results.
> :
> :Assuming...
> :
> :1. My_Aircraft.Mine is correct. (How is this determined?
> 
> Joachim has already mentioned code inspection.

See my arguments related to manual inspection as the only safeguard
against
errors in large systems.

> Also, if Mine is called anywhere in the code proper of the system and it has
> its own assertions, it will be validated by them. 

However, other posts have said that assertions shouldn't have
assertions.
What is the DBC position?

> However, these lower-level
> assertions won't be evaluated as part of higher-level assertion evaluation.
> 
> (For details, see OOSC-2, Chapter 11 - "Design by Contract: Building Reliable
> Software", Page 400 ff.)
> 
> In this sense, I suppose you could say there are "assertions about assertions" (meta-assertions). They help where they're needed most - where assertions are
> abstracted using boolean functions.
> 
> :Do assertions have assertions?
> 
> See above.
> 
> :What happens if an assertion's assertion fails, and how
> :is
> :   it distinguished from an assertion failure?)
> 
> Because assertion checking is turned off during assertion evaluation, this
> doesn't happen.
> 
> :2. Assume_Control is not called again with the same aircraft between the
> :   pre-condition and My_Aircraft.Add.
> :
> :3. Release_Control (I propose this as the opposite of Assume_Control) is
> :   not called between My_Aircraft.Add and the post-condition.
> 
> Neither of these concurrency issues exist under SCOOP because the runtime system
> automatically locks objects on behalf of the thread using them. It's simply
> impossible to have concurrent access to an object by multiple threads.

So, if an object is referenced by a thread, no other operations
associated with
the object can be called (object-locking, as opposed to
operation-locking)?
Doesn't this cause a few latency problems? For example, it's usually OK
for
multiple reads to occur concurrently, so long as no write is in process.
SCOOP
only permits sequential reads?

> 
> (For details of object locking under SCOOP, see OOSC-2, Section 30.6 -
> "Accessing separate objects", Page 982 ff.)
> 
> Ada, in contrast, does allow this - for example, if tasking is used in isolation.
> To overcome this deficiency, you have to either roll-your-own object protection
> (using semaphores, for example) or use protected objects. Using Ada protected
> objects is fine, but they lack the flexibility of Eiffel separate objects.

Just the opposite! Protected objects, for example, would allow
concurrent reads
if no timing issues result!

> 
> :4. There are no errors from other sources (e.g. extraneous code,
> :higher-tier
> :   documentation miscommunications).
> 
> I've already covered the case of extraneous code in a previous post.

Right - you said that you assume this won't happen. I was just noting
this
fact.

> 
> WRT documentation-related problems, these are outside the scope of any runtime
> error checking mechanism. DBC is *almost* a silver bullet but not quite. :)

Is DBC a methodology, or a "runtime error checking mechanism"? I
certainly know
methodologies that will help uncover extraneous code, and
requirements/design
issues. In fact, some methodologies emphasize the ability to manage
requirements
and design, since that's where many of the really difficult errors
emerge.

> 
> :Correct?
> 
> All of these issues are either non-issues or already catered for.

I'm not sure that saying "DBC won't help with this" is the same as
saying
that they are "non-issues."

Someone needs to decide if DBC is a coding guideline or a software
development
methodology. My concern is that it is touted as the former, but used as
the
latter.

> 
> :Also: If the post-condition fails, who provides the corrective action?
> 
> During development, you, the designer of the code (or your delegate) by fixing
> the problem. Additionally, in the case of critical software, you can add a
> rescue clause (exception handler) to keep the show on the road in production.

So, the client has to figure out what to do if your code fails? I
wouldn't
be inspired to confidence to reuse such code!

> 
> :Also: If My_Aircraft.Add is provided by a different programmer/team than
> :Assume_Control, does it call My_Aircraft.Mine (or a subset thereof)?
> 
> It doesn't matter. What's your point?..

It matters a lot! Again, if each team assumes the other does the call,
this
is bad news. If both teams do the call, this is not nice from a
efficiency
standpoint.

> 
> :Also: it's my understanding that DBC requires My_Aircraft.Mine be made
> :available
> :to the client of Assume_Control (no private pre-conditions). Is this the
> :case
> :here? Why or why not? Does this mean that the pre-condition may be
> :checked twice
> :before each call?
> 
> (Joachim's already answered this).
> 
> :> We now move on to the next
> :> component and repeat the process. Step-by-step, piece-by-piece we construct
> :> our reliable ATC system. We did so *incrementally* through a divide-and-conquer
> :> strategy and by being demanding in what we expected of callers and demanding
> :> of ourselves in producing the correct results.
> :
> :However, these results seem to be limited to making sure the code does what
> :you thought it was supposed to do.
> 
> Yes?..
> 
> :How are the other failure sources handled?
> 
> Clairvoyance. :)  Seriously, we already know that DBC can't identify all sources
> of error. 

But DBC is advertised as identifying other sources of error (e.g., the
code
does what's it's supposed to do, but only in a given environment).

> Other classes of error may be identified through other means that
> you're already well acquanted with.

Furthermore, the classes of error to which DBC is limited are
well-covered
through other means (beat to death, in fact). So, I'm still at a loss to
see what DBC brings to the table here. It doesn't address my main
problem
(requirements/design faults), it has limitations with respect to
implementation
language, it's not clear that it scales well, and it doesn't appear to
be internally
complete (big on error detection mechanisms, not much on how to derive
the
particular error sources, and not much on what to do after the error is
detected, for example).




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-31  0:00                                 ` Ken Garlington
@ 1997-08-07  0:00                                   ` Don Harrison
  1997-08-07  0:00                                     ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-07  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> Ken Garlington wrote:
:> 
:> :I responded elsewhere in this thread about difficulties in trying
:> :to accurately measure thread timings at the object level,
:> 
:> As I've already explained, SCOOP *does* support thread-level timing. The fact
:> this has not yet been tested in a realtime system doesn't invalidate any
:> logical arguments made about it.
:
:No, but then again, saying "X *does* support thread-level timing" isn't
:a
:logical argument, it's an assertion. And assertions, in the absence of
:any experience (either general experience from the author, or specific
:experience with X in a real system) are not particularly useful.

Not at all. It's more than an assertion - it's a fact. You may choose to 
disbelieve that fact for whatever reason but that doesn't alter its truth.


:Futhermore, here is a counter-argument to writing timing assertions
:at the object level:
:
:Using letters to denote objects, let's build a thread. The notation
:x{object}y means that the object is executed between x and y times.
:The arrows indicate that one object is executed before another object
:in the sequence. (For simplicity, we'll neglect objects calling
:objects).
:
:Thread: A -> B -> 1{C}4 -> D
:
:The max time for this thread is: A + B + 4*C + D, right?
:
:No!
:
:It also includes:
: 1. the entry/exit code for each object (4 times that, for C),
: 2. the time to start and stop the thread itself
: 3. Any time between object invocations "stolen" by other threads.

3) doesn't apply to SCOOP because all objects are locked.
1) and 2) can be included.

:If you start the measurement before the call to A, and stop it
:after the call to D, you only have to worry about #2 above
:(which is usually fixed). If you do the measurement at the object
:level, all three will skew your results. 

Not true. If you really want to get a clue on this, I suggest you get hold 
of OOSC-2 and read the chapter on concurrency. 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-07  0:00                               ` Don Harrison
@ 1997-08-07  0:00                                 ` Ken Garlington
  1997-08-09  0:00                                   ` Jim Cochrane
  1997-08-12  0:00                                   ` Don Harrison
  0 siblings, 2 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-07  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :Don Harrison wrote:
> :>
> :> Ken Garlington wrote:
> :>
> :> :Don Harrison wrote:
> :> :>
> :> :> What we want is a way to signal to the caller that they've made a mistake and
> :> :> need to take corrective action.
> :> :
> :> :If they don't know to check that they might have made a mistake,
> :>
> :> They *do* know because they get an exception.
> :
> :Not when they're _writing_ the code, unfortunately.
> 
> Yes, but we're not talking about writing the code. We're talking about execution.
> Even Smalltalkers can't write and execute at the same time. :)

Eiffel advocates need to decide: Is the primary value of assertions for
documentation
(as Meyer maintains) or to raise errors during execution (which has a
number of
drawbacks, including potentially postponing the detection of the problem
until well
after it is delivered).

> 
> :> :how do they know what corrective action they should take?
> :>
> :> To determine the right corrective action, they determine which specific
> :> (sub-)expression triggered the violation and work out the cause by conventional
> :> means, namely logical deduction.
> :
> :This brings up the second point. Why would a methodology/language go to
> :great lengths to _detect_ errors, but completely punt ("use conventional
> :means") to determine what to do _afterwards_?
> 
> DBC won't fix the errors for you. :)

No, but other methodologies do discuss error recovery techniques, and
how to
apply them. This is particularly important if the error won't be
uncovered
until after it is delivered.

> No tool can *think* for you. DBC does help identify and localise errors, but
> you're the one who must solve them.
> 
> :> :If the erroneous code is reused in another application, doesn't it carry
> :> :its error along with it?
> :>
> :> Yes, that's why it's important to fix it. :)
> :
> :Doesn't this erode the argument of using Eiffel to support reuse, if
> :errors
> :are so easily ported between applications?
> 
> No. If an error doesn't exist, it can't be ported.

Consider the Ariane case. The error didn't exist in the original
environment
(Ariane IV). The error only occured during execution in the Ariane 5
environment (a little too late to fix, unfortunately). Basing your
argument
on execution means that any latent error in the system, which might be
caught in other methodologies through the use of analysis and reviews,
will
be missed using DBC/Eiffel.

> 
> :> :What if the mistake is in your code, not the calling code?
> :>
> :> The context we're dicussing is a precondition, so I assume you mean a mistake
> :> in the precondition.  This will be obvious from the fact that the call is valid.
> :
> :Your code thinks the call is invalid. Who decides otherwise?
> 
> The developer running the program - by thinking.

Which is completely contradicted by the abve statements of using
assertions
for execution purposes.

The whole point of a methodology is to guide the thinking of an analyst.
It
doesn't sound like DBC/Eiffel has given you much in the way of guidance.

> 
> :> This is what I mean about the code proper validating assertions. (See my previous
> :> posts for details).
> :>
> :> :> What about case 2)? Here, we want to check that the work we delegated was
> :> :> done properly and acheived what we set out to do. In this case, we can
> :> :> perform some checks and raise and exception against ourselves to force us
> :> :> to fix the problem (possibly by delegating)..
> :> :>
> :> :>   procedure Assume_Control (Aircraft: Aircraft_Type) is
> :> :>   require not My_Aircraft.Mine (Aircraft)
> :> :>   begin
> :> :>     ...
> :> :>     My_Aircraft.Add (Aircraft);
> :> :>   ensure My_Aircraft.Mine (Aircraft)
> :> :>   end;
> :> :>
> :> :> which is our final solution. What we are now left with is a component of
> :> :> software that we know can only be executed under the intended conditions and
> :> :> can guarantee producing the required results.
> :> :
> :> :Assuming...
> :> :
> :> :1. My_Aircraft.Mine is correct. (How is this determined?
> :>
> :> Joachim has already mentioned code inspection.
> :
> :See my arguments related to manual inspection as the only safeguard
> :against
> :errors in large systems.
> 
> I'm not suggesting it should be.

More to the point, you haven't given any evidence that DBC/Eiffel has
any
particular advantage in this area.

> :> Also, if Mine is called anywhere in the code proper of the system and it has
> :> its own assertions, it will be validated by them.
> :
> :However, other posts have said that assertions shouldn't have
> :assertions.
> 
> We're talking about different things. See the OOSC-2 reference and my comments
> following for details..
> 
> :> However, these lower-level
> :> assertions won't be evaluated as part of higher-level assertion evaluation.
> :>
> :> (For details, see OOSC-2, Chapter 11 - "Design by Contract: Building Reliable
> :> Software", Page 400 ff.)
> :>
> :> In this sense, I suppose you could say there are "assertions about assertions" (meta-assertions). They help where they're needed most - where assertions are
> :> abstracted using boolean functions.
> 
> :> :2. Assume_Control is not called again with the same aircraft between the
> :> :   pre-condition and My_Aircraft.Add.
> :> :
> :> :3. Release_Control (I propose this as the opposite of Assume_Control) is
> :> :   not called between My_Aircraft.Add and the post-condition.
> :>
> :> Neither of these concurrency issues exist under SCOOP because the runtime system
> :> automatically locks objects on behalf of the thread using them. It's simply
> :> impossible to have concurrent access to an object by multiple threads.
> :
> :So, if an object is referenced by a thread, no other operations
> :associated with
> :the object can be called (object-locking, as opposed to
> :operation-locking)?
> 
> In theory, yes. In practice, I would expect SCOOP implementations to provide
> greater flexibility through optimisations (See below).
> 
> :Doesn't this cause a few latency problems? For example, it's usually OK
> :for
> :multiple reads to occur concurrently, so long as no write is in process.
> :SCOOP only permits sequential reads?
> 
> Optimisations could allow multiple concurrent queries (reads). The important
> is that exclusive access is *theoretically* guaranteed. What happens in practice
> doesn't matter so long as it's safe.

Has such automated optimization been done in practice? Isn't such an
optimization
on the same difficulty level as the toolset automatically generating the
correct assertions for each interface?

> 
> :> (For details of object locking under SCOOP, see OOSC-2, Section 30.6 -
> :> "Accessing separate objects", Page 982 ff.)
> :>
> :> Ada, in contrast, does allow this - for example, if tasking is used in isolation.
> :> To overcome this deficiency, you have to either roll-your-own object protection
> :> (using semaphores, for example) or use protected objects. Using Ada protected
> :> objects is fine, but they lack the flexibility of Eiffel separate objects.
> :
> :Just the opposite!
> 
> Incorrect.

Eiffel separate objects always lock the object. Ada protected records
can lock the
object for a given operation or not (at the designer's preference), can
requeue
requests, etc. More choices for the designer usually means additional
flexibility, I would think.

> 
> :Protected objects, for example, would allow concurrent reads
> :if no timing issues result!
> 
> See above. You lose flexibility with protected types because they're not
> inheritable and can't be used polymorphically.

But you gain flexibility in their timing capabilities (which is what we
were
discussing, remember? :). Given that the purpose of a protected type is
to
define time-based aspects the system, isn't this the more valuiable
flexibility
for this type of object?

> 
> :> :4. There are no errors from other sources (e.g. extraneous code,
> :> :higher-tier
> :> :   documentation miscommunications).
> :>
> :> I've already covered the case of extraneous code in a previous post.
> :
> :Right - you said that you assume this won't happen.
> 
> No, I said something else.

You said that you did not provide exhaustive coverage via assertions. If
that
doesn't mean that you assume the condition will not occur, what does it
mean?
That you assume it will occur, but do not address it?

> 
> :> WRT documentation-related problems, these are outside the scope of any runtime
> :> error checking mechanism. DBC is *almost* a silver bullet but not quite. :)
> :
> :Is DBC a methodology, or a "runtime error checking mechanism"?
> 
> Both.

Then what does it matter what a "runtime error checking mechanism" does?
The question remains: How does DBC address documentation-related
problems?

> 
> :I certainly know
> :methodologies that will help uncover extraneous code, and
> :requirements/design
> :issues. In fact, some methodologies emphasize the ability to manage
> :requirements
> :and design, since that's where many of the really difficult errors
> :emerge.
> 
> I agree this is an important area.

Given that, then if DBC does not address this area, it must be
deficient.

> 
> :Someone needs to decide if DBC is a coding guideline or a software
> :development
> :methodology. My concern is that it is touted as the former, but used as
> :the latter.
> 
> I don't see any problem with using it as both.

However, there is a serious problem when practitioners use it (and
discuss it) in terms of the former. Note the number of times in this
post, for example, that DBC has been described in terms of concrete
capabilities when the subject is code execution, but only vaguely
(if at all) when described as a methodology. For example:

1. How, specifically, does DBC support error detection prior to
execution?
(Not writing down potential error sources, but actually determining if
the
error exists in the particular application.)

2. By extension, how does DBC support error detection after reuse?

3. For those errors not discovered (which will presumably cause run-time
exceptions), how does DBC guide the designer to handle these exceptions
(which were not expected to occur)?

4. How does DBC help detect inconsistencies between code and
requirements,
or for that matter internal consistencies within the requirements?

Given that we both agree (as noted earlier in the post) that the key is
for the designer to think, how does a coding convention support such
thinking - not in terms of general OO concepts like polymorphism and
inheritance (which other languages, including Ada, have) but in terms of
error detection and correction?

> 
> :> :Also: If the post-condition fails, who provides the corrective action?
> :>
> :> During development, you, the designer of the code (or your delegate) by fixing
> :> the problem. Additionally, in the case of critical software, you can add a
> :> rescue clause (exception handler) to keep the show on the road in production.
> :
> :So, the client has to figure out what to do if your code fails?
> 
> Who said anything about clients? I said the designer of the code containing
> the postcondition - that is, the *supplier* in Eiffel parlance.

Wait a minute! Here's the possible scenarios:

1. The post-condition fails during initial development. In this case,
the
developer of the code fixes the problem (or changes the post-condition,
as unfortunately sometimes happens). However, how often is the
post-condition
going to fail at this point? The developer writes both the code and the
post-condition, so it's likely that they will match at that point.

2. The post-condition fails after delivery. The developer may no longer
be around
to fix the problem. Furthermore, if there is a rescue clause, what does
it do?
What guidance does DBC provide.

3. The post-condition fails during reuse development. Same outcome as
#2. This
is the most likely case for a post-condition failing - where the
environment
in which the module is used changes.

Any methodology that postpones finding errors until the code is reused
is going
to be difficult to sell as "reuse-friendly".

> 
> My original example, reinserted..
> 
> :  procedure Assume_Control (Aircraft: Aircraft_Type) is
> :  require not My_Aircraft.Mine (Aircraft)
> :  begin
> :    ...
> :    My_Aircraft.Add (Aircraft);
> :  ensure My_Aircraft.Mine (Aircraft)
> :  end;
> 
> :> :Also: If My_Aircraft.Add is provided by a different programmer/team than
> :> :Assume_Control, does it call My_Aircraft.Mine (or a subset thereof)?
> :>
> :> It doesn't matter. What's your point?..
> :
> :It matters a lot! Again, if each team assumes the other does the call,
> :this is bad news.
> 
> Correct me if I have this wrong, but you seem to be worried about too few checks
> and too many checks.
> 
> WRT too few checks, it's always the responsibility of the client to make sure
> the precondition is met. So, a check will always be made.

Hasn't this whole discussion been in terms of how to detect errors in
the code?
Isn't it a little naive to assume that the code will be written
correctly as a
precondition for finding errors in the code?

For that matter, if it's the client's responsibility, and it doesn't
hurt if
the assertion is not performed by the object being used, then doesn't
this
cut the legs out of an argument of Eiffel's power? Pretty much any
language
can provide assertions for the client to manually call prior to using an
operation.

> 
> WRT too many checks, an implementation may optimise out any redundant checks
> - for example if a precondition check is already done by a caller. This minimises
> the number of redundant checks.

You're assuming a lot about automated optimizations across object
interface
boundaries. Is there evidence that Eiffel compilers do such
optimizations
successfully? Worse, you're again in the "proof by execution" mode. What
does
this extra code do in terms of readability, for example?

> :If both teams do the call, this is not nice from a
> :efficiency standpoint.
> 
> See above.

Ditto. Any methodology that says, "Write as much code as you want, the
compiler will optimize it" doesn't seem to be a strong methodology, in
my opinion.

> 
> :> Other classes of error may be identified through other means that
> :> you're already well acquanted with.
> :
> :Furthermore, the classes of error to which DBC is limited are
> :well-covered
> :through other means (beat to death, in fact).
> 
> The difference is it does a better job of it.

We'll just have to agree to disagree on this one. Again, I would rather
have a methodology that helps me think about the issues vs. coding them.

> 
> :So, I'm still at a loss to
> :see what DBC brings to the table here. It doesn't address my main
> :problem (requirements/design faults),
> 
> Not entirely true. DBC can highlight specification/design inconsistencies.
> (See my previous posts). Otherwise, I agree.

I saw your previous posts. I quote from the line above:

  "WRT documentation-related problems, these are outside the scope of
  any runtime error checking mechanism. DBC is *almost* a silver bullet
  but not quite."

Please summarize your arguments/evidence that DBC helps find
documentation-
related problems.

> 
> :it has limitations with respect to implementation language,
> 
> More accurate is to say that most languages provide limited support for it.

Two responses:

1. I was discussing limitations in Eiffel, and

2. Other Eiffel experts disagree with you with regard to other
languages:

See the post on Internet newsgroup comp.lang.eiffel "Re: Papers on the
Ariane-5
crash and Design by Contract," Jean-Marc Jezequel, 1997/03/18: "Ada's
subtype
declarations are a kind of contract, that could be documented as such.
Design
by contract is not specific to Eiffel. You can do it with any language,
just
because it is a way of designing!"

> 
> :it's not clear that it scales well,
> 
> Not true.

Can you provide evidence to the contrary?

See Internet newsgroup comp.lang.eiffel post "Re: Papers on the
Ariane-5 crash and Design by Contract," Jean-Marc Jezequel,
1997/03/18: "...at least in the case of Ariane 501, simple assertions
(a la Eiffel and other languages) would have been expressive enough to
specify the fatal hidden assumption. Whether the last point scales up
to a full sized mission critical system is still an open question.
I'm quite confident it is so, but I've only my own experience with telco
systems to back it up."

> 
> :and it doesn't appear to be internally complete (big on error detection
> :mechanisms, not much on how to derive the particular error sources,
> 
> That's because they're typically blindingly obvious! Why? Because error detection
> is more localised.

But interface errors, by definition, are not localized. They are
generated
due to the interaction between objects (in some cases, a long thread of
object interactions). The Ariane 5 case is a perfect example of this.

Requirements/design mismatches, similarly, are not localized since the
requirements are usually not written in terms of objects. One of the
designer's jobs is to map the requirements to objects. Even for
requirements that are object-oriented, they are usually a much higher
level than the implementation.

Again, you're thinking of run-time error detection. This is the worst
place
to detect errors. Consider, for example, the errors made in the Eiffel
implementation of the scaling routine presented in their Ariane paper.
If these errors were "blindingly obvious", why did it take a year for
anyone to say anything about them?

> 
> :and not much on what to do after the error is detected, for example).
> 
> Again, this is usually blindingly obvious.

Any time someone says something is obvious, without any evidence or
argument to support it, I pretty much assume that the point is ceded.
I will say that if error recovery is blindingly obvious, then there's
a lot of work in the fault tolerance world that's apparently just a
waste of money. :)

> 
> All of these points have been made before.

Unfortunately, I think you're right. It doesn't seem as though we're
communicating very effectively. I'll concede the argument to you.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-07  0:00                                   ` Don Harrison
@ 1997-08-07  0:00                                     ` Ken Garlington
  1997-08-13  0:00                                       ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-08-07  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :Don Harrison wrote:
> :>
> :> Ken Garlington wrote:
> :>
> :> :I responded elsewhere in this thread about difficulties in trying
> :> :to accurately measure thread timings at the object level,
> :>
> :> As I've already explained, SCOOP *does* support thread-level timing. The fact
> :> this has not yet been tested in a realtime system doesn't invalidate any
> :> logical arguments made about it.
> :
> :No, but then again, saying "X *does* support thread-level timing" isn't
> :a
> :logical argument, it's an assertion. And assertions, in the absence of
> :any experience (either general experience from the author, or specific
> :experience with X in a real system) are not particularly useful.
> 
> Not at all. It's more than an assertion - it's a fact. You may choose to
> disbelieve that fact for whatever reason but that doesn't alter its truth.

I hadn't realized we were dealing in terms of a "higher truth" that
doesn't
require argument or evidence. I never argue religion, so we'll have to
just
disagree on this one.

> 
> :Futhermore, here is a counter-argument to writing timing assertions
> :at the object level:
> :
> :Using letters to denote objects, let's build a thread. The notation
> :x{object}y means that the object is executed between x and y times.
> :The arrows indicate that one object is executed before another object
> :in the sequence. (For simplicity, we'll neglect objects calling
> :objects).
> :
> :Thread: A -> B -> 1{C}4 -> D
> :
> :The max time for this thread is: A + B + 4*C + D, right?
> :
> :No!
> :
> :It also includes:
> : 1. the entry/exit code for each object (4 times that, for C),
> : 2. the time to start and stop the thread itself
> : 3. Any time between object invocations "stolen" by other threads.
> 
> 3) doesn't apply to SCOOP because all objects are locked.

(3) represents the time _in between_ object invocations. If you are
saying that a thread (a series of object invocations) cannot be
interrupted at _any point_, then that pretty much eliminates
concurrency, doesn't it?

I have a feeling that we're just not communicating on this issue. My
experience is in real-time systems, and I think I'm just not
properly conveying the issues involved in developing those systems.

> 1) and 2) can be included.
> 
> :If you start the measurement before the call to A, and stop it
> :after the call to D, you only have to worry about #2 above
> :(which is usually fixed). If you do the measurement at the object
> :level, all three will skew your results.
> 
> Not true. If you really want to get a clue on this, I suggest you get hold
> of OOSC-2 and read the chapter on concurrency.

Once I see an appeal to authority, I pretty much have to assume the
discussion is over. We'll just have to agree to disagree on this as
well.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-31  0:00                             ` Ken Garlington
@ 1997-08-07  0:00                               ` Don Harrison
  1997-08-07  0:00                                 ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-07  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> Ken Garlington wrote:
:> 
:> :Don Harrison wrote:
:> :>
:> :> What we want is a way to signal to the caller that they've made a mistake and
:> :> need to take corrective action.
:> :
:> :If they don't know to check that they might have made a mistake,
:> 
:> They *do* know because they get an exception.
:
:Not when they're _writing_ the code, unfortunately. 

Yes, but we're not talking about writing the code. We're talking about execution. 
Even Smalltalkers can't write and execute at the same time. :)


:> :how do they know what corrective action they should take?
:> 
:> To determine the right corrective action, they determine which specific
:> (sub-)expression triggered the violation and work out the cause by conventional
:> means, namely logical deduction.
:
:This brings up the second point. Why would a methodology/language go to
:great lengths to _detect_ errors, but completely punt ("use conventional
:means") to determine what to do _afterwards_?

DBC won't fix the errors for you. :)

No tool can *think* for you. DBC does help identify and localise errors, but 
you're the one who must solve them. 


:> :If the erroneous code is reused in another application, doesn't it carry
:> :its error along with it?
:> 
:> Yes, that's why it's important to fix it. :)
:
:Doesn't this erode the argument of using Eiffel to support reuse, if
:errors
:are so easily ported between applications?

No. If an error doesn't exist, it can't be ported.


:> :What if the mistake is in your code, not the calling code?
:> 
:> The context we're dicussing is a precondition, so I assume you mean a mistake
:> in the precondition.  This will be obvious from the fact that the call is valid.
:
:Your code thinks the call is invalid. Who decides otherwise?

The developer running the program - by thinking.


:> This is what I mean about the code proper validating assertions. (See my previous
:> posts for details).
:> 
:> :> What about case 2)? Here, we want to check that the work we delegated was
:> :> done properly and acheived what we set out to do. In this case, we can
:> :> perform some checks and raise and exception against ourselves to force us
:> :> to fix the problem (possibly by delegating)..
:> :>
:> :>   procedure Assume_Control (Aircraft: Aircraft_Type) is
:> :>   require not My_Aircraft.Mine (Aircraft)
:> :>   begin
:> :>     ...
:> :>     My_Aircraft.Add (Aircraft);
:> :>   ensure My_Aircraft.Mine (Aircraft)
:> :>   end;
:> :>
:> :> which is our final solution. What we are now left with is a component of
:> :> software that we know can only be executed under the intended conditions and
:> :> can guarantee producing the required results.
:> :
:> :Assuming...
:> :
:> :1. My_Aircraft.Mine is correct. (How is this determined?
:> 
:> Joachim has already mentioned code inspection.
:
:See my arguments related to manual inspection as the only safeguard
:against
:errors in large systems.

I'm not suggesting it should be.


:> Also, if Mine is called anywhere in the code proper of the system and it has
:> its own assertions, it will be validated by them. 
:
:However, other posts have said that assertions shouldn't have
:assertions.

We're talking about different things. See the OOSC-2 reference and my comments
following for details..

:> However, these lower-level
:> assertions won't be evaluated as part of higher-level assertion evaluation.
:> 
:> (For details, see OOSC-2, Chapter 11 - "Design by Contract: Building Reliable
:> Software", Page 400 ff.)
:> 
:> In this sense, I suppose you could say there are "assertions about assertions" (meta-assertions). They help where they're needed most - where assertions are
:> abstracted using boolean functions.


:> :2. Assume_Control is not called again with the same aircraft between the
:> :   pre-condition and My_Aircraft.Add.
:> :
:> :3. Release_Control (I propose this as the opposite of Assume_Control) is
:> :   not called between My_Aircraft.Add and the post-condition.
:> 
:> Neither of these concurrency issues exist under SCOOP because the runtime system
:> automatically locks objects on behalf of the thread using them. It's simply
:> impossible to have concurrent access to an object by multiple threads.
:
:So, if an object is referenced by a thread, no other operations
:associated with
:the object can be called (object-locking, as opposed to
:operation-locking)?

In theory, yes. In practice, I would expect SCOOP implementations to provide 
greater flexibility through optimisations (See below).

:Doesn't this cause a few latency problems? For example, it's usually OK
:for
:multiple reads to occur concurrently, so long as no write is in process.
:SCOOP only permits sequential reads?

Optimisations could allow multiple concurrent queries (reads). The important 
is that exclusive access is *theoretically* guaranteed. What happens in practice
doesn't matter so long as it's safe.


:> (For details of object locking under SCOOP, see OOSC-2, Section 30.6 -
:> "Accessing separate objects", Page 982 ff.)
:> 
:> Ada, in contrast, does allow this - for example, if tasking is used in isolation.
:> To overcome this deficiency, you have to either roll-your-own object protection
:> (using semaphores, for example) or use protected objects. Using Ada protected
:> objects is fine, but they lack the flexibility of Eiffel separate objects.
:
:Just the opposite! 

Incorrect.

:Protected objects, for example, would allow concurrent reads
:if no timing issues result!

See above. You lose flexibility with protected types because they're not  
inheritable and can't be used polymorphically.

:> :4. There are no errors from other sources (e.g. extraneous code,
:> :higher-tier
:> :   documentation miscommunications).
:> 
:> I've already covered the case of extraneous code in a previous post.
:
:Right - you said that you assume this won't happen. 

No, I said something else. 


:> WRT documentation-related problems, these are outside the scope of any runtime
:> error checking mechanism. DBC is *almost* a silver bullet but not quite. :)
:
:Is DBC a methodology, or a "runtime error checking mechanism"? 

Both.

:I certainly know
:methodologies that will help uncover extraneous code, and
:requirements/design
:issues. In fact, some methodologies emphasize the ability to manage
:requirements
:and design, since that's where many of the really difficult errors
:emerge.

I agree this is an important area.


:Someone needs to decide if DBC is a coding guideline or a software
:development
:methodology. My concern is that it is touted as the former, but used as
:the latter.

I don't see any problem with using it as both.


:> :Also: If the post-condition fails, who provides the corrective action?
:> 
:> During development, you, the designer of the code (or your delegate) by fixing
:> the problem. Additionally, in the case of critical software, you can add a
:> rescue clause (exception handler) to keep the show on the road in production.
:
:So, the client has to figure out what to do if your code fails? 

Who said anything about clients? I said the designer of the code containing 
the postcondition - that is, the *supplier* in Eiffel parlance.

My original example, reinserted..

:  procedure Assume_Control (Aircraft: Aircraft_Type) is
:  require not My_Aircraft.Mine (Aircraft)
:  begin
:    ...
:    My_Aircraft.Add (Aircraft);
:  ensure My_Aircraft.Mine (Aircraft)
:  end;

:> :Also: If My_Aircraft.Add is provided by a different programmer/team than
:> :Assume_Control, does it call My_Aircraft.Mine (or a subset thereof)?
:> 
:> It doesn't matter. What's your point?..
:
:It matters a lot! Again, if each team assumes the other does the call,
:this is bad news. 

Correct me if I have this wrong, but you seem to be worried about too few checks
and too many checks. 

WRT too few checks, it's always the responsibility of the client to make sure 
the precondition is met. So, a check will always be made.
 
WRT too many checks, an implementation may optimise out any redundant checks 
- for example if a precondition check is already done by a caller. This minimises
the number of redundant checks.

:If both teams do the call, this is not nice from a
:efficiency standpoint.

See above.


:> Other classes of error may be identified through other means that
:> you're already well acquanted with.
:
:Furthermore, the classes of error to which DBC is limited are
:well-covered
:through other means (beat to death, in fact). 

The difference is it does a better job of it.

:So, I'm still at a loss to
:see what DBC brings to the table here. It doesn't address my main
:problem (requirements/design faults), 

Not entirely true. DBC can highlight specification/design inconsistencies.
(See my previous posts). Otherwise, I agree. 

:it has limitations with respect to implementation language, 

More accurate is to say that most languages provide limited support for it.

:it's not clear that it scales well, 

Not true. 

:and it doesn't appear to be internally complete (big on error detection 
:mechanisms, not much on how to derive the particular error sources, 

That's because they're typically blindingly obvious! Why? Because error detection
is more localised.

:and not much on what to do after the error is detected, for example).

Again, this is usually blindingly obvious. 


All of these points have been made before. 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-07-28  0:00                     ` Robert S. White
@ 1997-08-09  0:00                       ` Marinos J. Yannikos
  1997-08-10  0:00                         ` Robert S. White
  1997-08-11  0:00                         ` Peter Hamer
  0 siblings, 2 replies; 255+ messages in thread
From: Marinos J. Yannikos @ 1997-08-09  0:00 UTC (permalink / raw)



In article <5rh12t$jl0$1@flood.weeg.uiowa.edu>, Robert S. White wrote:
>  I hope you never have to do safety-critical hard real-time programming
>with more than a very few tasks running.  You have never hear of a 
>deadlock?  Race condition?  Sure you try to design to avoid such things,
>but you can never be sure that you have really successsfully avoided
>all timing sensitivities until you _test_ for them!  The cold HARD rule
>is that if the machine code changes, then regression tests _must_ be 
>done.

(straying off-topic, but second opinions might be interesting sometimes)

There is a school of thought which insists that verifying hard real-time
systems by testing them is pointless, since you can hardly simulate all
possible events, how they interact, occur at the same time ("avalanches")
etc. Some other approaches might be taken, a good one is (IMHO) static
scheduling and checking of time constraints, which is possible if you
reduce the scope of the language the code is written in (e.g. no infinite
loops allowed). Have a look at the MARS project if you're interested:

http://www.vmars.tuwien.ac.at (not much there, unfortunately)
ftp://ftp.vmars.tuwien.ac.at/pub/papers/rr-01-89.ps.Z
ftp://ftp.vmars.tuwien.ac.at/pub/papers/rr-01-91.ps.Z
ftp://ftp.vmars.tuwien.ac.at/pub/papers/rr-02-91.ps.Z
ftp://ftp.vmars.tuwien.ac.at/pub/papers/rr-11-91.ps.Z
ftp://ftp.vmars.tuwien.ac.at/pub/papers/rr-12-91.ps.Z
ftp://ftp.vmars.tuwien.ac.at/pub/papers/rr-02-92.ps.Z
ftp://ftp.vmars.tuwien.ac.at/pub/papers/rr-11-92.ps.Z
ftp://ftp.vmars.tuwien.ac.at/pub/papers/rr-04-93.ps.Z

(Lots of research reports about timing and Modula-r...)

A funny coincidence is that during a seminar in '93 or so at that department
I had to compare Eiffel to Modula-r regarding suitability for hard real-time
systems (the former I knew nothing about and have not read much about since
then), the latter I had the luck to have worked on for a student project.

Note that I'm slightly biased, and not being enough of a real-time
person I may easily have missed some limitations/disadvantages of the MARS
and Modula-r approach.

-nino
-- 
Please change the last part of my address to "at" if you're replying by mail.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-07  0:00                                 ` Ken Garlington
@ 1997-08-09  0:00                                   ` Jim Cochrane
  1997-08-11  0:00                                     ` Paul Johnson
  1997-08-12  0:00                                   ` Don Harrison
  1 sibling, 1 reply; 255+ messages in thread
From: Jim Cochrane @ 1997-08-09  0:00 UTC (permalink / raw)



In article <33E9ADE9.4709@flash.net>,
Ken Garlington  <kennieg@flash.net> wrote:
>Don Harrison wrote:
>> 
>> Ken Garlington wrote:
>> 
>> :Don Harrison wrote:
>> :>
>> :> Ken Garlington wrote:
>> :>
>> :> :Don Harrison wrote:
>> :> :>
>> :> :> What we want is a way to signal to the caller that they've made a mistake and
>> :> :> need to take corrective action.
>> :> :
>> :> :If they don't know to check that they might have made a mistake,
>> :>
>> :> They *do* know because they get an exception.
>> :
>> :Not when they're _writing_ the code, unfortunately.
>> 
>> Yes, but we're not talking about writing the code. We're talking about execution.
>> Even Smalltalkers can't write and execute at the same time. :)
>
>Eiffel advocates need to decide: Is the primary value of assertions for
>documentation
>(as Meyer maintains) or to raise errors during execution (which has a
>number of
>drawbacks, including potentially postponing the detection of the problem
>until well
>after it is delivered).

I think the most important use of Eiffel assertions (specifically
require, ensure, and (class) invariant) is for documentation - that is,
to provide a precise specification of the precondition and postcondition
for each public method and of the class invariant.  Specifications that
are not codable can still be documented as comments.  Tools that are part
of the standard Eiffel environment automatically extract these specifications
so that a programmer who is using a class will have access to the
documentation of the class's interface without needing to look at the
class implementation.

> ...
>> 
>> :Someone needs to decide if DBC is a coding guideline or a software
>> :development
>> :methodology. My concern is that it is touted as the former, but used as
>> :the latter.
>> 
>> I don't see any problem with using it as both.
>
>However, there is a serious problem when practitioners use it (and
>discuss it) in terms of the former. Note the number of times in this
>post, for example, that DBC has been described in terms of concrete
>capabilities when the subject is code execution, but only vaguely
>(if at all) when described as a methodology. For example:
>
>1. How, specifically, does DBC support error detection prior to
>execution?
>(Not writing down potential error sources, but actually determining if
>the
>error exists in the particular application.)

The concept of design by contract is simply an extension of the ideas
presented by Dijkstra, Gries, and others on the design of correct
programs.  An important component of these ideas is the specification of a
precise pre- and post-condition for each coded procedure.  The extensions
made to this component by the principle of design by contract include
adapting it to an object-oriented system (by adding class invariants
and having the procedures belong to a class) and providing language
support for these specifications.

To address the above question in this context, design by contract can
be used as part of a formal development process that uses design and
code inspections as a means of detecting and removing design and code
defects.  The technique of precisely specifying class interfaces,
aided with tools to extract this specification to make it easily
available, enhances the inspection process by making these interfaces
explicit.  Thus, for example, when the implementation of a method m that
uses class X is inspected, the use of X's methods by m can be examined
to determine if m uses X's methods correctly; this is done by checking,
for example, for a call of X.a in m, that the precondition of X.a will
be true when the call is made.  Additionally, m's postcondition can
be used during an inspection to check if it will always be true by
analyzing the implementation of m - that is, by answering the question:
When m's implementation is executed, will it always terminate with
the postcondition true?

Thus (in my opinion), design by contract is not a method.  Rather it
is a technique that is a useful component of a method.  The contribution
of the this technique is that it ensures a precise and explicit
specification of a class interface so that the use of the interface
can be examined by means of its pre-conditions to make sure that it
is used correctly, and the implementation of the interface can be
examined by means of its post-conditions and class invariant to make
sure that it is implemented correctly.  In any object-oriented design,
all class interfaces will have specifications.  If the specifications
are not explicitly documented, it will be more difficult to use the
interface correctly.  When the specifications are explicitly documented,
it becomes easier to use the interface correctly, as well as easier to
detect defects in the use or implementation of the interface.

>
>2. By extension, how does DBC support error detection after reuse?

If I understand what you're asking, design by contract can be used to
detect errors in the use of a reusable component by examining the
use of the component by the client code and determining if the
pre-conditions specified by the reusable component's interface are
true for every call in the client code of a method belonging to the
interface.

>
>3. For those errors not discovered (which will presumably cause run-time
>exceptions), how does DBC guide the designer to handle these exceptions
>(which were not expected to occur)?

I think that the originator of the concept of design by contract,
Meyer, has presented some guidelines for handling exceptions.  However,
although these guidelines may be helpful, I think the designer of
the software is going to need to decide how to handle each situation
where an exception could occur.

>
>4. How does DBC help detect inconsistencies between code and
>requirements,
>or for that matter internal consistencies within the requirements?

Again, (in my opinion) design by contract is not a method; and it cannot
solve these problems.  It should be used as part of a method.  Areas
such as these that are not addressed by design by contract, should
be addressed by means of other method components.  Design by contract
could help to detect inconsistencies between code and requirements,
since it makes the interface specifications of the code explicit, thus
making it easier to detect such inconsistencies simply because the
documentation of the specifications is available; but it cannot be
used as the only means to detect these inconsistencies.

From your post, my impression is that you are assuming that design
by contract is a method whose purpose is to develop software as free
from defects as possible.  I think if you adjust your view and look
at it as a technique or tool that is part of such a method, this may
clear up some of the confusion.  In other words, the application of
design by contract will not guarantee high quality software.  This is
only possible if it is applied wisely as part of a comprehensive method.
And even a comprehensive method cannot guarantee high quality software;
it is also necessary to apply one's own exertion, intelligence, and
wisdom.  A method may guide us in developing high quality software,
but we will still need to make difficult decisions.  Regardless of the
method used, a poorly made decision can detract from the quality of the
software we are developing.


Jim Cochrane
jtc@dimensional.com

>
>Given that we both agree (as noted earlier in the post) that the key is
>for the designer to think, how does a coding convention support such
>thinking - not in terms of general OO concepts like polymorphism and
>inheritance (which other languages, including Ada, have) but in terms of
>error detection and correction?
>
>> 
>> :> :Also: If the post-condition fails, who provides the corrective action?
>> :>
>> :> During development, you, the designer of the code (or your delegate) by fixing
>> :> the problem. Additionally, in the case of critical software, you can add a
>> :> rescue clause (exception handler) to keep the show on the road in production.
>> :
>> :So, the client has to figure out what to do if your code fails?
>> 
>> Who said anything about clients? I said the designer of the code containing
>> the postcondition - that is, the *supplier* in Eiffel parlance.
>
>Wait a minute! Here's the possible scenarios:
>
>1. The post-condition fails during initial development. In this case,
>the
>developer of the code fixes the problem (or changes the post-condition,
>as unfortunately sometimes happens). However, how often is the
>post-condition
>going to fail at this point? The developer writes both the code and the
>post-condition, so it's likely that they will match at that point.
>
>2. The post-condition fails after delivery. The developer may no longer
>be around
>to fix the problem. Furthermore, if there is a rescue clause, what does
>it do?
>What guidance does DBC provide.
>
>3. The post-condition fails during reuse development. Same outcome as
>#2. This
>is the most likely case for a post-condition failing - where the
>environment
>in which the module is used changes.
>
>Any methodology that postpones finding errors until the code is reused
>is going
>to be difficult to sell as "reuse-friendly".
>
>> 
>> My original example, reinserted..
>> 
>> :  procedure Assume_Control (Aircraft: Aircraft_Type) is
>> :  require not My_Aircraft.Mine (Aircraft)
>> :  begin
>> :    ...
>> :    My_Aircraft.Add (Aircraft);
>> :  ensure My_Aircraft.Mine (Aircraft)
>> :  end;
>> 
>> :> :Also: If My_Aircraft.Add is provided by a different programmer/team than
>> :> :Assume_Control, does it call My_Aircraft.Mine (or a subset thereof)?
>> :>
>> :> It doesn't matter. What's your point?..
>> :
>> :It matters a lot! Again, if each team assumes the other does the call,
>> :this is bad news.
>> 
>> Correct me if I have this wrong, but you seem to be worried about too few checks
>> and too many checks.
>> 
>> WRT too few checks, it's always the responsibility of the client to make sure
>> the precondition is met. So, a check will always be made.
>
>Hasn't this whole discussion been in terms of how to detect errors in
>the code?
>Isn't it a little naive to assume that the code will be written
>correctly as a
>precondition for finding errors in the code?
>
>For that matter, if it's the client's responsibility, and it doesn't
>hurt if
>the assertion is not performed by the object being used, then doesn't
>this
>cut the legs out of an argument of Eiffel's power? Pretty much any
>language
>can provide assertions for the client to manually call prior to using an
>operation.
>
>> 
>> WRT too many checks, an implementation may optimise out any redundant checks
>> - for example if a precondition check is already done by a caller. This minimises
>> the number of redundant checks.
>
>You're assuming a lot about automated optimizations across object
>interface
>boundaries. Is there evidence that Eiffel compilers do such
>optimizations
>successfully? Worse, you're again in the "proof by execution" mode. What
>does
>this extra code do in terms of readability, for example?
>
>> :If both teams do the call, this is not nice from a
>> :efficiency standpoint.
>> 
>> See above.
>
>Ditto. Any methodology that says, "Write as much code as you want, the
>compiler will optimize it" doesn't seem to be a strong methodology, in
>my opinion.
>
>> 
>> :> Other classes of error may be identified through other means that
>> :> you're already well acquanted with.
>> :
>> :Furthermore, the classes of error to which DBC is limited are
>> :well-covered
>> :through other means (beat to death, in fact).
>> 
>> The difference is it does a better job of it.
>
>We'll just have to agree to disagree on this one. Again, I would rather
>have a methodology that helps me think about the issues vs. coding them.
>
>> 
>> :So, I'm still at a loss to
>> :see what DBC brings to the table here. It doesn't address my main
>> :problem (requirements/design faults),
>> 
>> Not entirely true. DBC can highlight specification/design inconsistencies.
>> (See my previous posts). Otherwise, I agree.
>
>I saw your previous posts. I quote from the line above:
>
>  "WRT documentation-related problems, these are outside the scope of
>  any runtime error checking mechanism. DBC is *almost* a silver bullet
>  but not quite."
>
>Please summarize your arguments/evidence that DBC helps find
>documentation-
>related problems.
>
>> 
>> :it has limitations with respect to implementation language,
>> 
>> More accurate is to say that most languages provide limited support for it.
>
>Two responses:
>
>1. I was discussing limitations in Eiffel, and
>
>2. Other Eiffel experts disagree with you with regard to other
>languages:
>
>See the post on Internet newsgroup comp.lang.eiffel "Re: Papers on the
>Ariane-5
>crash and Design by Contract," Jean-Marc Jezequel, 1997/03/18: "Ada's
>subtype
>declarations are a kind of contract, that could be documented as such.
>Design
>by contract is not specific to Eiffel. You can do it with any language,
>just
>because it is a way of designing!"
>
>> 
>> :it's not clear that it scales well,
>> 
>> Not true.
>
>Can you provide evidence to the contrary?
>
>See Internet newsgroup comp.lang.eiffel post "Re: Papers on the
>Ariane-5 crash and Design by Contract," Jean-Marc Jezequel,
>1997/03/18: "...at least in the case of Ariane 501, simple assertions
>(a la Eiffel and other languages) would have been expressive enough to
>specify the fatal hidden assumption. Whether the last point scales up
>to a full sized mission critical system is still an open question.
>I'm quite confident it is so, but I've only my own experience with telco
>systems to back it up."
>
>> 
>> :and it doesn't appear to be internally complete (big on error detection
>> :mechanisms, not much on how to derive the particular error sources,
>> 
>> That's because they're typically blindingly obvious! Why? Because error detection
>> is more localised.
>
>But interface errors, by definition, are not localized. They are
>generated
>due to the interaction between objects (in some cases, a long thread of
>object interactions). The Ariane 5 case is a perfect example of this.
>
>Requirements/design mismatches, similarly, are not localized since the
>requirements are usually not written in terms of objects. One of the
>designer's jobs is to map the requirements to objects. Even for
>requirements that are object-oriented, they are usually a much higher
>level than the implementation.
>
>Again, you're thinking of run-time error detection. This is the worst
>place
>to detect errors. Consider, for example, the errors made in the Eiffel
>implementation of the scaling routine presented in their Ariane paper.
>If these errors were "blindingly obvious", why did it take a year for
>anyone to say anything about them?
>
>> 
>> :and not much on what to do after the error is detected, for example).
>> 
>> Again, this is usually blindingly obvious.
>
>Any time someone says something is obvious, without any evidence or
>argument to support it, I pretty much assume that the point is ceded.
>I will say that if error recovery is blindingly obvious, then there's
>a lot of work in the fault tolerance world that's apparently just a
>waste of money. :)
>
>> 
>> All of these points have been made before.
>
>Unfortunately, I think you're right. It doesn't seem as though we're
>communicating very effectively. I'll concede the argument to you.
>
>> 
>> Don.
>> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
>> Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-09  0:00                       ` Marinos J. Yannikos
@ 1997-08-10  0:00                         ` Robert S. White
  1997-08-11  0:00                         ` Peter Hamer
  1 sibling, 0 replies; 255+ messages in thread
From: Robert S. White @ 1997-08-10  0:00 UTC (permalink / raw)



In article <slrn5upcrm.jue.someone_else@a0.complang.tuwien.ac.at>, 
nino@complang.tuwien.ac.look-in-sig says...

>There is a school of thought which insists that verifying hard real-time
>systems by testing them is pointless, since you can hardly simulate all
>possible events, how they interact, occur at the same time ("avalanches")
>etc. 

  I'll grant that regression Formal Qualification Tests do not verify
all possible timing combinations, but the point is to run the embedded
system through some normal usage scenarios to _try_ to find defects
that have escaped the net of design reviews, code inspections, and
low level tests.  The level and degree (usage extremes) of the 
regression tests depend on what the safety requirements, warrenty 
requirements, customer, software quality assurance, etc. demand versus
time, equipment and money resources.  Yes it is a level of gray, not
black and white.

> Some other approaches might be taken, a good one is (IMHO) static
>scheduling and checking of time constraints, which is possible if you
>reduce the scope of the language the code is written in (e.g. no infinite
>loops allowed).

  It would be a difficult paradigm shift for my co-workers and I to 
give up using tasks with infinite loops that wait for events to be
signaled or for certain amounts of time to elapse.  Of course this
also requires the ability to detect task "cycle slips".  I've been
doing this for the last 12 years using both Jovial and Ada83 and
have been able to deploy reliable hard real time systems.  This is
not just a language issue as RTE's and RTOS's can be used by a lot
of different languages. I'm trying to visualize just what this
approach you are talking about would involve that does not use
any loops.  Guess I have to copy down one of the papers you cite.
_____________________________________________________________________
Robert S. White         -- An embedded systems software engineer





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-09  0:00                                   ` Jim Cochrane
@ 1997-08-11  0:00                                     ` Paul Johnson
  1997-08-11  0:00                                       ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Paul Johnson @ 1997-08-11  0:00 UTC (permalink / raw)



In article <5siqrr$3of@jupiter.milkyway.org>, jtc@jupiter.milkyway.org says...

>I think the most important use of Eiffel assertions (specifically
>require, ensure, and (class) invariant) is for documentation [...]

While this is true, the importance of executable assertions should not
be under-estimated.  Execution acts as a safeguard on the inspection and
documentation parts.  We've all worked on projects where the documentation
has been put off or not done because of schedule pressure.  Everyone agrees
that this is a bad thing, but it still keeps on happening.  Executable
assertions won't let you do this.

A mature software process can also use this property by tracking assertion
failures and using them to monitor and improve inspection procedures.



> [...] I think the designer of
>the software is going to need to decide how to handle each situation
>where an exception could occur.

This is true.  It depends on the context of the application.  For example
a real-time control system would shut down, re-initialise and try to
continue.  For safety or mission-critical apps it would let the back-up
take over (yes, I've read the Ariane 5 report).  For an interactive
application it would try to save the user data, put up an informative
message, and close down.

Paul

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-09  0:00                       ` Marinos J. Yannikos
  1997-08-10  0:00                         ` Robert S. White
@ 1997-08-11  0:00                         ` Peter Hamer
  1997-08-11  0:00                           ` "Paul E. Bennett"
  1 sibling, 1 reply; 255+ messages in thread
From: Peter Hamer @ 1997-08-11  0:00 UTC (permalink / raw)



Marinos J. Yannikos wrote:
> 
> There is a school of thought which insists that verifying hard real-time
> systems by testing them is pointless, since you can hardly simulate all
> possible events, how they interact, occur at the same time ("avalanches")
> etc. <snip>

Insufficient, certainly.

Pointless? Ask the Hubble space telescope people if they have
reconsidered the wisdom of not testing for gross errors [they
needed a space-walk to fix things]. Of course, they were absolutely
right: the available tests would not have detected errors of the size
they were designing for; just the one they had! 
  
Years ago somebody invented the analogy of the robot dentist. You
were to be the first lucky customer. What validation would you like
to have been carried out first? Would you be happy if validation was
restricted to method X; and no testing had been carried out?

Peter




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-11  0:00                         ` Peter Hamer
@ 1997-08-11  0:00                           ` "Paul E. Bennett"
  0 siblings, 0 replies; 255+ messages in thread
From: "Paul E. Bennett" @ 1997-08-11  0:00 UTC (permalink / raw)



In article <33EF06BE.730F@nortel.co.uk> pgh@nortel.co.uk "Peter Hamer" writes:

> Years ago somebody invented the analogy of the robot dentist. You
> were to be the first lucky customer. What validation would you like
> to have been carried out first? Would you be happy if validation was
> restricted to method X; and no testing had been carried out?

I have heard of one robot doing Prostate surgery. I know I wouldn't have 
volunteered to be the first on that one unless I had performed a full audit 
of the design, manufacturing and maintenance organisations. Even then I might 
have still been wary. Things I know I would have been on the look-out for
in those areas would be more with the design, manufacture and maintenance
processes and procedures employed by the organisations, proof that these
were followed and that a "Safety Culture" existed in the organisations 
concerned. Language and tools are hardly an issue.

-- 
Paul E. Bennett ................... <peb@transcontech.co.uk>
Transport Control Technology Ltd.   <http://www.tcontec.demon.co.uk/>
+44 (0)117-9499861                  <enquiry@transcontech.co.uk>
Going Forth Safely





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-11  0:00                                     ` Paul Johnson
@ 1997-08-11  0:00                                       ` Ken Garlington
  1997-08-12  0:00                                         ` Mark A Biggar
  1997-08-13  0:00                                         ` Paul Johnson
  0 siblings, 2 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-11  0:00 UTC (permalink / raw)



Paul Johnson wrote:
> 
> In article <5siqrr$3of@jupiter.milkyway.org>, jtc@jupiter.milkyway.org says...
> 
> >I think the most important use of Eiffel assertions (specifically
> >require, ensure, and (class) invariant) is for documentation [...]
> 
> While this is true, the importance of executable assertions should not
> be under-estimated.  Execution acts as a safeguard on the inspection and
> documentation parts.  We've all worked on projects where the documentation
> has been put off or not done because of schedule pressure.  Everyone agrees
> that this is a bad thing, but it still keeps on happening.  Executable
> assertions won't let you do this.

Leaving out executable assertions is just as easy as leaving out
non-executable
ones, isn't it?

> A mature software process can also use this property by tracking assertion
> failures and using them to monitor and improve inspection procedures.

Is there a systematic method for reviewing code to determine if the
right
number and type of assertions have been added? This would seem to be the
more critical issue. Without any assertions, the number of assertions
failures can be predicted with some confidence :)

> 
> > [...] I think the designer of
> >the software is going to need to decide how to handle each situation
> >where an exception could occur.
> 
> This is true.  It depends on the context of the application.  For example
> a real-time control system would shut down, re-initialise and try to
> continue.  For safety or mission-critical apps it would let the back-up
> take over (yes, I've read the Ariane 5 report).  For an interactive
> application it would try to save the user data, put up an informative
> message, and close down.

I think this is a little over-simplified. For example, in each case:

1. A real-time feedback system would probably not want to shut down,
   even for a small interval.

2. As you note, turning over control to a backup is not always a good
idea.

3. Interactive application error messages can be missed (see the recent
   InterNIC risk).

Real-world exception responses in complex systems can be extremely
difficult to analyze.

> 
> Paul
> 
> --
> Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
> +44 1245 242244         +-----------+-----------------------------------------+
> Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
> Home: <Paul@treetop.demon.co.uk>    | standards, all different.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-07  0:00                                 ` Ken Garlington
  1997-08-09  0:00                                   ` Jim Cochrane
@ 1997-08-12  0:00                                   ` Don Harrison
  1997-08-12  0:00                                     ` Jon S Anthony
                                                       ` (2 more replies)
  1 sibling, 3 replies; 255+ messages in thread
From: Don Harrison @ 1997-08-12  0:00 UTC (permalink / raw)



Ken Garlington wrote (with deletions):

:Don Harrison wrote:

[...]

:> No. If an error doesn't exist, it can't be ported.
:
:Consider the Ariane case. The error didn't exist in the original
:environment
:(Ariane IV). The error only occured during execution in the Ariane 5
:environment (a little too late to fix, unfortunately). Basing your
:argument
:on execution means that any latent error in the system, which might be
:caught in other methodologies through the use of analysis and reviews,
:will
:be missed using DBC/Eiffel.

I disagree. I'll explain below..

[...]

:> :> (For details of object locking under SCOOP, see OOSC-2, Section 30.6 -
:> :> "Accessing separate objects", Page 982 ff.)
:> :>
:> :> Ada, in contrast, does allow this - for example, if tasking is used in isolation.
:> :> To overcome this deficiency, you have to either roll-your-own object protection
:> :> (using semaphores, for example) or use protected objects. Using Ada protected
:> :> objects is fine, but they lack the flexibility of Eiffel separate objects.
:> :
:> :Just the opposite!
:> 
:> Incorrect.
:
:Eiffel separate objects always lock the object. Ada protected records
:can lock the
:object for a given operation or not (at the designer's preference), 

IMO, this is something the designer is better off leaving to the compiler as 
it can be expected to do a better job of it. If Ada protected types allow 
the designer to explicitly leave objects unlocked (which doesn't appear to 
be supported by the Ada95 Rationale), then they are more permissive but 
in a detrimental way, IMO.

:can requeue requests, 

IMO, the situations in which you would use "requeue" are better handled by 
designing differently - perhaps by using an additional class. If anything,
"requeue" probably encourages poor design.

:etc. 

What are these?

More choices for the designer usually means additional
:flexibility, I would think.

Drawing some inspiration from Robert Dewar, "flexibility" and "permissiveness" 
have at their root the same meaning but differ wrt the user perceives a benefit 
or detriment respectively.

[...]

:> :Someone needs to decide if DBC is a coding guideline or a software
:> :development
:> :methodology. My concern is that it is touted as the former, but used as
:> :the latter.
:> 
:> I don't see any problem with using it as both.
:
:However, there is a serious problem when practitioners use it (and
:discuss it) in terms of the former. Note the number of times in this
:post, for example, that DBC has been described in terms of concrete
:capabilities when the subject is code execution, but only vaguely
:(if at all) when described as a methodology..

Your basic worry seems to be that DBC doesn't appear to be an all-embracing, 
formal software engineering methodology.

At this stage, I think you're right. I think the reason why is that DBC 
probably hasn't been used in the context of *formal* software engineering. 
If it had, then it would have been integrated with other complementary 
reliability-enhancing techniques. 

IMO, a methodology centred on DBC, would also include stuff about systematic
testing of components. In the Ariane case, this might involve bolting an IRS
onto some test bench and stimulating it with Ariane 5 data. This may require
simulating the surrounding environment. Then, any assertions assuming Ariane 4 
inputs would be violated (as would the Ada constraint_error). In general, 
the extra checking afforded by DBC would mean more bugs would be identified 
than if it wasn't used. (Yes, I know there is no difference wrt the one that 
caused the failure.)

[...]

:> :So, I'm still at a loss to
:> :see what DBC brings to the table here. It doesn't address my main
:> :problem (requirements/design faults),
:> 
:> Not entirely true. DBC can highlight specification/design inconsistencies.
:> (See my previous posts). Otherwise, I agree.
:
:I saw your previous posts. I quote from the line above:
:
:  "WRT documentation-related problems, these are outside the scope of
:  any runtime error checking mechanism. DBC is *almost* a silver bullet
:  but not quite."

Right person, wrong quote and wrong context. If it's any help to you, the 
comments I'm referring to were about mutually validating requirements. I 
acknowledged not all documentation errors were covered. 

[...]

:> :it's not clear that it scales well,
:> 
:> Not true.
:
:Can you provide evidence to the contrary?

I've already covered this. Nick's experience also endorses it.

[...]

:> :and not much on what to do after the error is detected, for example).
:> 
:> Again, this is usually blindingly obvious.
:> 
:Any time someone says something is obvious, without any evidence or
:argument to support it, I pretty much assume that the point is ceded.

No, it just means I'm just getting impatient. :(
 

Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-12  0:00                                   ` Don Harrison
  1997-08-12  0:00                                     ` Jon S Anthony
@ 1997-08-12  0:00                                     ` Ken Garlington
  1997-08-23  0:00                                     ` W. Wesley Groleau x4923
  2 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-12  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote (with deletions):
> 
> :Don Harrison wrote:
> 
> [...]
> 
> :> No. If an error doesn't exist, it can't be ported.
> :
> :Consider the Ariane case. The error didn't exist in the original
> :environment
> :(Ariane IV). The error only occured during execution in the Ariane 5
> :environment (a little too late to fix, unfortunately). Basing your
> :argument
> :on execution means that any latent error in the system, which might be
> :caught in other methodologies through the use of analysis and reviews,
> :will
> :be missed using DBC/Eiffel.
> 
> I disagree. I'll explain below..
> 
> [...]
> 
> :> :> (For details of object locking under SCOOP, see OOSC-2, Section 30.6 -
> :> :> "Accessing separate objects", Page 982 ff.)
> :> :>
> :> :> Ada, in contrast, does allow this - for example, if tasking is used in isolation.
> :> :> To overcome this deficiency, you have to either roll-your-own object protection
> :> :> (using semaphores, for example) or use protected objects. Using Ada protected
> :> :> objects is fine, but they lack the flexibility of Eiffel separate objects.
> :> :
> :> :Just the opposite!
> :>
> :> Incorrect.
> :
> :Eiffel separate objects always lock the object. Ada protected records
> :can lock the
> :object for a given operation or not (at the designer's preference),
> 
> IMO, this is something the designer is better off leaving to the compiler as
> it can be expected to do a better job of it. If Ada protected types allow
> the designer to explicitly leave objects unlocked (which doesn't appear to
> be supported by the Ada95 Rationale), then they are more permissive but
> in a detrimental way, IMO.

Since such decisions are fundamental to the design of real-time systems,
isn't this statement equivalent to "it's better to have tool X design
my software autonomously than for a human to do it?"

I think when you actually start building complex real-time systems,
you will see that more locking is not equivalent to better design.

> 
> :can requeue requests,
> 
> IMO, the situations in which you would use "requeue" are better handled by
> designing differently - perhaps by using an additional class. If anything,
> "requeue" probably encourages poor design.
> 
> :etc.
> 
> What are these?
> 
> More choices for the designer usually means additional
> :flexibility, I would think.
> 
> Drawing some inspiration from Robert Dewar, "flexibility" and "permissiveness"
> have at their root the same meaning but differ wrt the user perceives a benefit
> or detriment respectively.

Very true. In Ada, the "permissiveness" is defined as allowing the
programmer
to do that which is historically error-prone (e.g. the copy principal).
Do you
have evidence that enforced blocking on _all_ objects solves a common
problem in the design of real-time systems, particularly when excessive
blocking often leads to deadlock?

> 
> [...]
> 
> :> :Someone needs to decide if DBC is a coding guideline or a software
> :> :development
> :> :methodology. My concern is that it is touted as the former, but used as
> :> :the latter.
> :>
> :> I don't see any problem with using it as both.
> :
> :However, there is a serious problem when practitioners use it (and
> :discuss it) in terms of the former. Note the number of times in this
> :post, for example, that DBC has been described in terms of concrete
> :capabilities when the subject is code execution, but only vaguely
> :(if at all) when described as a methodology..
> 
> Your basic worry seems to be that DBC doesn't appear to be an all-embracing,
> formal software engineering methodology.

Absolutely. In fact, based on some of the discussions, it seems to be
reduced almost to a coding standard in some practitioner's mind. (This
isn't entirely fair to DBC, of course, but it highlights the problem
with calling DBC a "methodology" vs. a "tool" or "technique".)

> At this stage, I think you're right. I think the reason why is that DBC
> probably hasn't been used in the context of *formal* software engineering.
> If it had, then it would have been integrated with other complementary
> reliability-enhancing techniques.
> 
> IMO, a methodology centred on DBC, would also include stuff about systematic
> testing of components. In the Ariane case, this might involve bolting an IRS
> onto some test bench and stimulating it with Ariane 5 data. This may require
> simulating the surrounding environment. Then, any assertions assuming Ariane 4
> inputs would be violated (as would the Ada constraint_error). In general,
> the extra checking afforded by DBC would mean more bugs would be identified
> than if it wasn't used. (Yes, I know there is no difference wrt the one that
> caused the failure.)
> 
> [...]
> 
> :> :So, I'm still at a loss to
> :> :see what DBC brings to the table here. It doesn't address my main
> :> :problem (requirements/design faults),
> :>
> :> Not entirely true. DBC can highlight specification/design inconsistencies.
> :> (See my previous posts). Otherwise, I agree.
> :
> :I saw your previous posts. I quote from the line above:
> :
> :  "WRT documentation-related problems, these are outside the scope of
> :  any runtime error checking mechanism. DBC is *almost* a silver bullet
> :  but not quite."
> 
> Right person, wrong quote and wrong context. If it's any help to you, the
> comments I'm referring to were about mutually validating requirements. I
> acknowledged not all documentation errors were covered.

But all of my requirements are in the documentation! By definition, my
code
is an _implementation_ of those requirements, not the _definition_ of
them.

> 
> [...]
> 
> :> :it's not clear that it scales well,
> :>
> :> Not true.
> :
> :Can you provide evidence to the contrary?
> 
> I've already covered this. Nick's experience also endorses it.

I must have missed it. Could you list the projects again? I saw some
hypothetical discussion of why it might scale, but I think Mr. Jezequel
is correct: There isn't sufficient _evidence_ to say that it _will_
scale.

> 
> [...]
> 
> :> :and not much on what to do after the error is detected, for example).
> :>
> :> Again, this is usually blindingly obvious.
> :>
> :Any time someone says something is obvious, without any evidence or
> :argument to support it, I pretty much assume that the point is ceded.
> 
> No, it just means I'm just getting impatient. :(

Unfortunate. Having the patience to reconsider the "blindingly obvious"
has usually led me to my best work.

I find that if I can't put together a logical argument, preferably
backed
by observable evidence, then I'm probably working on emotion rather
than insight. A long time ago, I thought it was "blindingly obvious"
that
OO approaches wouldn't work in real-time systems. After I started
considering the issue further, and doing demonstration projects using
OO techniques, I found I was dead wrong.

> 
> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-11  0:00                                       ` Ken Garlington
@ 1997-08-12  0:00                                         ` Mark A Biggar
  1997-08-19  0:00                                           ` Robert Dewar
  1997-08-13  0:00                                         ` Paul Johnson
  1 sibling, 1 reply; 255+ messages in thread
From: Mark A Biggar @ 1997-08-12  0:00 UTC (permalink / raw)



In article <33EFCCE4.4CE0@flash.net> Ken.Garlington@computer.org writes:
>Paul Johnson wrote:
>Leaving out executable assertions is just as easy as leaving out
>non-executable
>ones, isn't it?

Sure, even if assertions are required by the language syntax,
you can always just use the assertion "true" :-).
You can't even make using the assertion "true" illegal as there are
cases where the assertion "true" is exactly the correct assertion to 
use; for example, using "true" as a precondition for a method documents the
fact that it has NO enviromential requirements at all. (E.G. a random
number routine or the Unix exit() call).  And, what is the postcondition
for printf()?

--
Mark Biggar
mab@wdl.lmco.com







^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-12  0:00                                   ` Don Harrison
@ 1997-08-12  0:00                                     ` Jon S Anthony
  1997-08-13  0:00                                       ` Ted Velkoff
  1997-08-13  0:00                                       ` Don Harrison
  1997-08-12  0:00                                     ` Ken Garlington
  1997-08-23  0:00                                     ` W. Wesley Groleau x4923
  2 siblings, 2 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-08-12  0:00 UTC (permalink / raw)



In article <EEsF5y.F5H@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> it can be expected to do a better job of it. If Ada protected types allow 
> the designer to explicitly leave objects unlocked (which doesn't appear to 
> be supported by the Ada95 Rationale), then they are more permissive but 
> in a detrimental way, IMO.

You're not twigging this stuff.  The objects can be unlocked for
_read_ access, but never for any update access.  Now you can make a
value judgement that this is worthless or misguided, but that's
different.


> :can requeue requests, 
> 
> IMO, the situations in which you would use "requeue" are better handled by 
> designing differently - perhaps by using an additional class. If anything,
> "requeue" probably encourages poor design.

Requeue is specifically there to eliminate in principle any timing
errors.  The way this works is somewhat subtle, so maybe you are not
twigging this either.


> simulating the surrounding environment. Then, any assertions
> assuming Ariane 4 inputs would be violated (as would the Ada
> constraint_error). In general, the extra checking afforded by DBC
> would mean more bugs would be identified than if it wasn't
> used. (Yes, I know there is no difference wrt the one that caused
> the failure.)

The problem with this is the simple observation of "why would the
assertions be there in the first place?"  After all, in the particular
case at hand, they were _intentionally_ removed.  And with perfectly
sound engineering principles in mind.  Assertions in the code _cannot_
capture the constraints presumed for the context of use.  This has to
come from somewhere else (external documentation, "instructions",
"warrenty notes", whatever.)  The odd thing here is that this point
should be "blindingly obvious", to use one of your phrases.

> :Any time someone says something is obvious, without any evidence or
> :argument to support it, I pretty much assume that the point is ceded.
> 
> No, it just means I'm just getting impatient. :(

Same here - In SPADES.

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                         ` Samuel Mize
@ 1997-08-13  0:00                                           ` Robert A Duff
  1997-08-14  0:00                                             ` Jon S Anthony
  1997-08-15  0:00                                             ` Don Harrison
  0 siblings, 2 replies; 255+ messages in thread
From: Robert A Duff @ 1997-08-13  0:00 UTC (permalink / raw)



In article <33F20113.738F@link.com>, Samuel Mize  <smize@link.com> wrote:
>Don Harrison wrote:
>> 
>> Jon S Anthony wrote:
>[about Ada protected objects]
>> :The objects can be unlocked for
>> :_read_ access, but never for any update access.
>> 
>> Care to give an example?
>
>"Locked" is a common term, but its application to Ada is not
>defined by the Ada Reference Manual (ARM), so it may be
>unclear or accidentally misleading.

>The ARM refers to protected operations being "blocked" if they
>cannot "acquire" the "execution resource associated with a
>protected object" (ARM 9.4(18)).

No, that's not how the RM defines "blocked".  A task is blocked when it
is sitting on an entry queue, waiting for the barrier to become true,
and in various other situations, but it is not considered blocked when
it is waiting for the lock on a protected object.  It does have to wait
for the lock, of course, but we don't call that state "blocked".

To answer Don's question: protected objects can be locked for read-only
access, or for read-write access.  Read-only access does not exclude
other readers.

The Ada folks seem to be missing Don's earlier point, which is that in
Eiffel you can lock a bunch of objects all at once, whereas in Ada, you
lock just one object at a time (that is, a protected operation X.Op(Y, Z)
locks X, but not Y and Z (in Ada).

>In other words, a protected object can have functions and
>procedures (treating entries are a type of procedure).

The difference between protected procedures and entries is that entries
can "block" (in the Ada RM sense), whereas protected procedures cannot.

- Bob




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                         ` Ken Garlington
@ 1997-08-13  0:00                                           ` Ted Velkoff
  1997-08-14  0:00                                             ` Matt Austern
  1997-08-15  0:00                                             ` Ken Garlington
  1997-08-14  0:00                                           ` Nick Leaton
  1 sibling, 2 replies; 255+ messages in thread
From: Ted Velkoff @ 1997-08-13  0:00 UTC (permalink / raw)



Ken Garlington responded to an earlier post of mine:
> 
> This is certainly reasonable. However, once the execution capabilities
> are removed, it seems fair to ask what Eiffel provides that comments
> (available in most langauges) don't provide. If there is not a
> significant
> difference, then Eiffel would not be any better (in this context) than
> any other language, so long as the DBC principles were followed.
> 

In my experience, there is a significant difference.  I will not presume 
to make a scientific claim; rather I will offer a personal, anecdotal 
example.

About two years ago, I built a modest enhancement to a system which 
amounted to 4K lines each of Ada and C++.  In the package specs and 
module headers I included preconditions, postconditions and invariants 
as comments.  In the Ada bodies, I wrote if-then-else clauses to test 
preconditions (violations led to a chain of exceptions raised out to 
the main program).  In the C++ implementations, I included conditionally 
compiled calls to the assert macro (which does a core dump and spits out 
a file and line number) for preconditions and trivial 
postconditions.

This approach worked really well for me because I was very motivated and 
willing to do certain things.  Those things included: Step 1) write the 
assertions as comments in the specs; Step 2) update comments in the 
specs when testing revealed missing assertions (it's against the rules 
to introduce a precondition and not tell anyone about it - a contract 
with secret codicils, so to speak); Step 3) write the code to test the 
conditions, raise exceptions and generate a trace (in the Ada code).  

This approach was not without flaws:  Flaw 1) In the Ada code, for 
instance, there was no conditional compilation; to remove the assertion 
monitoring would have been a tedious exercise;  Flaw 2) I didn't even 
attempt to monitor postconditions - this is harder, even for simple ones 
(e.g. count = old count + 1); Flaw 3) as implied above, information had 
to be kept in synch in two places: the specs and bodies.

In my opinion, this won't scale up to a large team.  20% might see the 
benefit and be willing to do the many tedious manual tasks I described; 
20% will see no benefit, and even if they did, wouldn't do it; the other 
60% could be persuaded that it would help but wouldn't tolerate the 
extra upfront burden and wouldn't adopt it (in particular, steps 2 and 
3).  I should say I haven't tried it out on a team; this is pure 
conjecture.  (If anything, this appraisal is optimistic.)

Meanwhile at home I write software in Eiffel, where assertions are built 
into the language.  In Eiffel, all I do is Step 1: write the 
pre/post-conditions and invariants.  I don't need to do Step 2 (keep 
spec and body in synch) since in Eiffel, the spec (properly speaking, 
the short form) is automatically generated by tools.  Step 3, (coding 
the assertion tests, handling failures, providing useful diagnostics) is 
provided automatically by the environment.  Furthermore, the three flaws 
are eliminated: 1) with a compile-time switch I can turn off monitoring 
(I don't have to go through and "comment out" reams of code); 2) it's 
easy to monitor post-conditions, since this is provided by the tools 
(caveat - this is useful for testing and integration; postcondition 
monitoring necessarily incurs a performance penalty); 3) mentioned 
above, there is no spec/body redundancy to be managed by the programmer.

Returning to my view of scalability, I think the same 20% of 
programmers would love to work in a programming environment with these 
capabilities, 20% would still dislike it; but the other 60% - I think 
they would like it.  I say that because the cost/benefit is easier to 
see.  It doesn't take much time to write assertions, so when the rest 
comes for free (documentation and testing), programmers will want to 
write them.

Finally, I'll contrast Eiffel's assertions with comments (in any 
language).  I conjecture that because they can be monitored easily, 
Eiffel's assertions affect programmer psychology.  As a supplier, if I 
write postconditions or invariants as comments, I might be merely making 
promises.  If I know those assertions are easily monitored, I will be 
careful about what I promise: the auditor might show up at any minute.

I can imagine that Eiffel may not be suitable for certain real-time 
applications mentioned in this thread.  Nevertheless, I am convinced 
that a large number of software projects would benefit from employing 
"Design By Contract", and that Eiffel is the only language I know 
that makes its application practical and cost-effective 

-- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-11  0:00                                       ` Ken Garlington
  1997-08-12  0:00                                         ` Mark A Biggar
@ 1997-08-13  0:00                                         ` Paul Johnson
  1997-08-13  0:00                                           ` Ken Garlington
  1 sibling, 1 reply; 255+ messages in thread
From: Paul Johnson @ 1997-08-13  0:00 UTC (permalink / raw)



In article <33EFCCE4.4CE0@flash.net>, kennieg@flash.net says...

>Leaving out executable assertions is just as easy as leaving out
>non-executable ones, isn't it?

Yes, but once they are in there, they are checked against the code.

>> A mature software process can also use this property by tracking assertion
>> failures and using them to monitor and improve inspection procedures.
>
>Is there a systematic method for reviewing code to determine if the
>right number and type of assertions have been added? 

Yes.  The assertions should express the requirements that the rest of the
system has for the class.  A class with no assertions basically promises
to take any input and either do something or nothing.

(Aside: it puts me in mind of a company prospectus from the South Sea
Bubble: "An undertaking of great advantage, but nobody to know what it is".)

The client code can be checked against the assertions: if the client
relies on undocumented (i.e. unasserted) behaviour then it is at fault.
On the other hand if the supplier class fails to promise anything useful
then its a useless piece of code anyway, and can be rejected on those
grounds.  The whole point is to document the interface, and then check
the documentation for correctness.

Paul.

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                         ` Paul Johnson
@ 1997-08-13  0:00                                           ` Ken Garlington
  1997-08-15  0:00                                             ` Paul Johnson
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-08-13  0:00 UTC (permalink / raw)



Paul Johnson wrote:
> 
> The client code can be checked against the assertions: if the client
> relies on undocumented (i.e. unasserted) behaviour then it is at fault.
> On the other hand if the supplier class fails to promise anything useful
> then its a useless piece of code anyway, and can be rejected on those
> grounds.  The whole point is to document the interface, and then check
> the documentation for correctness.

Against what? All you have is the code and the assertions created as
part
of the code. Checking them against each other determines internal
consistency between the two, but that's all. Based on the studies I've
seen, most errors aren't to pure internal inconsistencies at the code
level.

It's difficult to explain a software methodology to someone who only
sees
one step: coding. I'd have to type in several pages worth of software
engineering textbook to even try. So (and I hate this phrase!) we'll
just
have to agree to disagree.

> 
> Paul.
> 
> --
> Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
> +44 1245 242244         +-----------+-----------------------------------------+
> Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
> Home: <Paul@treetop.demon.co.uk>    | standards, all different.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                       ` Ted Velkoff
  1997-08-13  0:00                                         ` Jon S Anthony
@ 1997-08-13  0:00                                         ` Ken Garlington
  1997-08-13  0:00                                           ` Ted Velkoff
  1997-08-14  0:00                                           ` Nick Leaton
  1 sibling, 2 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-13  0:00 UTC (permalink / raw)



Ted Velkoff wrote:
> 
> There is an important distinction between including/removing assertions
> and monitoring/not monitoring them during execution.  One of the
> principal benefits of Eiffel is the fact that assertions remain in the
> code (where programmers will see them) even if they are not tested
> dynamically (this is controlled by a compile-time switch).  Whether or
> not this would have saved Ariane V, the documentation and testing
> benefits of Eiffel's assertions would benefit many, many software
> projects.

This is certainly reasonable. However, once the execution capabilities
are removed, it seems fair to ask what Eiffel provides that comments
(available in most langauges) don't provide. If there is not a
significant
difference, then Eiffel would not be any better (in this context) than
any other language, so long as the DBC principles were followed.

> 
> -- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                       ` Don Harrison
@ 1997-08-13  0:00                                         ` Ken Garlington
  1997-08-14  0:00                                           ` Don Harrison
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-08-13  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken asked for evidence that SCOOP supports thread-level timing.
> 
> Ken Garlington wrote:
> 
> Why are they collectively locked?
> Answer: So that processing can be performed under known conditions without
>   interference from other threads (helping to avoid race conditions). Also,
>   so that we know up-front that we have all the resources we needed (helping
>   to avoid deadlock).

What happens if the resource is unavailable (already locked by a
lower-priority
thread, for example)?

It seems to me that, locking _all_ objects involved in an operation
(without
regard to whether they guard a sensitive resource, such as a data store
that
can be written by multiple threads) means that the latencies associated
with
the threads goes up dramatically, particularly if the locking is
transitive.
Priority inversion would also seem to be much more likely.

Ada has a different approach. Consider a fairly simple case of a value
that
is read by some tasks, written by others. Clearly, if a thread is
writing
a value, it should start and complete that operation before any other
access to that resource. Similarly, any attempt to read the resource
should
start and complete before any write to the resource begins. However,
a read by a low-priority task can be suspended to permit a
higher-priority
task to read the same resouirce (assuming no side-effects of the read).
As I understand it, you would prohibit this benign "interference." Thus,
the high-priority task (which may run much more frequently than the
low-priority task) is unnecessarily delayed, potentially causing it
to meet it's deadline.

You claimed that the compiler could optimize the timing properties of
the system; I would be interested in seeing such a compiler. Today,
there are tools that can help the designer analyze the system; I have
yet to see one that could do a real-time architecture design
autonomously!

> 
> When are they collectively locked?
> Answer: When they're supplied as parameters to an operation.
> 
> What if they're not supplied as parameters?
> Answer: They always *are* (in the case of concurrent (separate) objects.
>   In the case of sequential (non-separate) object, we don't care because
>   we know they're local to the calling thread.
> 
> See the example below..
> 
> :> :Futhermore, here is a counter-argument to writing timing assertions
> :> :at the object level:
> :> :
> :> :Using letters to denote objects, let's build a thread. The notation
> :> :x{object}y means that the object is executed between x and y times.
> :> :The arrows indicate that one object is executed before another object
> :> :in the sequence. (For simplicity, we'll neglect objects calling
> :> :objects).
> :> :
> :> :Thread: A -> B -> 1{C}4 -> D
> :> :
> :> :The max time for this thread is: A + B + 4*C + D, right?
> :> :
> :> :No!
> :> :
> :> :It also includes:
> :> : 1. the entry/exit code for each object (4 times that, for C),
> :> : 2. the time to start and stop the thread itself
> :> : 3. Any time between object invocations "stolen" by other threads.
> :>
> :> 3) doesn't apply to SCOOP because all objects are locked.
> :
> :(3) represents the time _in between_ object invocations.
> 
> You might code your example in pseudo-SCOOP:
> 
> Assuming separate (allocated to different threads) entities
> 
>   my_p: separate P
>   my_q: separate Q
>   my_r: separate R
>   my_s: separate S
> 
> and operation
> 
>   do_something (p: separate P; q: separate Q; r: separate R; s: separate S) is
>   local
>     start_time: time
>     duration: ...
>   do
>     start_time := time_now
>     p.a
>     q.b
>     loop (4 times)
>       r.c
>     end
>     s.d
>     duration := time_now - start_time
>     ...
>   end
> 
> the call
> 
>   do_something (my_p, my_q, my_r, my_s)

It wouldn't catch the extry/exit time of do_something, but
that's not a big deal. I see you've missed the original
part of the thread. The poster suggested writing 
assertions (post-conditions) on P, Q, R, and S as the
way to do this, which (as I said) won't work effectively.
Your approach is at the thread level, not the object
level, which is the way I would have done it as well.
So, in fact, we agree that the original post is in
error (I assume).

> 
> will do the required actions and measure the elapsed time.
> 
> Note that all four objects are locked for the block between "do" and "end".
> This means that there is no intervening time between calls to them and there
> is no opportunity for any other threads to jump in and make a mess of things.

Just out of curiosity, can the "local" section make reference to these
objects?

Also, how is "do_something" attached to a hardware event? What are the
implications
of doing so?

> Note that this offers more protection than Ada protected objects which are
> only locked on single object basis. As you will see later, this also removes
> the need for a "requeue" statement.

True. However, you pay a pretty terrible price for this protection, as
far as I can tell. I can see several systems which literally could not
be implemented under these rules.

> 
> :If you are saying that a thread (a series of object invocations) cannot be
> :interrupted at _any point_, then that pretty much eliminates
> :concurrency, doesn't it?
> 
> No, it just means it's more controlled (and safer). There is a complementary
> library mechanism called "express messages" which allows pre-emption of threads.

Perhaps this "express messages" is the backdoor which I have to believe
a real system would need.

Correct me if I'm wrong, but no other thread can run while do_something
is
executing? Or are you saying it can be interrupted, just that no other
thread
can access the objects referenced in the parameter list (or any objects
referenced in _their_ parameter lists? )?

> 
> :I have a feeling that we're just not communicating on this issue.
> 
> True.
> 
> :My experience is in real-time systems, and I think I'm just not
> :properly conveying the issues involved in developing those systems.
> 
> Likewise.
> 
> :> :If you start the measurement before the call to A, and stop it
> :> :after the call to D, you only have to worry about #2 above
> :> :(which is usually fixed). If you do the measurement at the object
> :> :level, all three will skew your results.
> :>
> :> Not true. If you really want to get a clue on this, I suggest you get hold
> :> of OOSC-2 and read the chapter on concurrency.
> 
> Sorry, Ken. I was a bit rude here.

A little confusing, too, since you _do_ in fact start the measurement
befoire the call to A (or P.A) and after the last call in your example!

> 
> :Ken Garlington wrote (about Ada protected types):
> 
> ::can requeue requests,
> 
> I wrote:
> 
> :IMO, the situations in which you would use "requeue" are better handled by
> :designing differently - perhaps by using an additional class.
> 
> Sorry, this is wrong. The problem in Ada which "requeue" is designed to deal
> with doesn't arise in SCOOP because successive calls to the same separate
> object are atomic. That is, the object doesn't get unlocked between calls.

True. However, the question still stands: What happens if a thread
attempts to
access a locked (or otherwise unavailable) resource? I can use requeue
in
these situations; what do you do?

> For example,
> 
>   do_something (a: separate A) is
>   do
>     a.do_x
>     a.do_y
>   end
> 
> does exactly what we expect. There is no need for do_x to "requeue" do_y.

That's not how requeue works, as I understand it. The issue is more: you
attempt to do a.do_x, and someone else has already seized the resource,
or
there is some other time-based reason why a.do_x is unavailable.

> IMO, "requeue" is a wokaround to a design flaw in Ada's concurrency - namely
> locking at the object level. Further, it's a *deficient* workaround because
> supplier objects are forced to do things (do_y) that should be the
> responsibility of clients (do_something).

It depends. A "requeue" may be needed because of the state of the
object, and may not be related to the state of do_something.

> :If anything, "requeue" probably encourages poor design.
> 
> .. as I've just explained.

Sorry, don't see it.

I think you would need to apply SCOOP to some fairly complex
real-time systems to see the problems I'm discussing. So long
as all the objects have short lifetimes, and no priority issues
are around, I would assume it seems to work fine for simple systems.


> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-12  0:00                                     ` Jon S Anthony
@ 1997-08-13  0:00                                       ` Ted Velkoff
  1997-08-13  0:00                                         ` Jon S Anthony
  1997-08-13  0:00                                         ` Ken Garlington
  1997-08-13  0:00                                       ` Don Harrison
  1 sibling, 2 replies; 255+ messages in thread
From: Ted Velkoff @ 1997-08-13  0:00 UTC (permalink / raw)



Jon S Anthony wrote:
> 
> The problem with this is the simple observation of "why would the
> assertions be there in the first place?"  After all, in the particular
> case at hand, they were _intentionally_ removed.  And with perfectly
> sound engineering principles in mind.  Assertions in the code _cannot_
> capture the constraints presumed for the context of use.  This has to
> come from somewhere else (external documentation, "instructions",
> "warrenty notes", whatever.) [...]
> 

There is an important distinction between including/removing assertions 
and monitoring/not monitoring them during execution.  One of the 
principal benefits of Eiffel is the fact that assertions remain in the 
code (where programmers will see them) even if they are not tested 
dynamically (this is controlled by a compile-time switch).  Whether or 
not this would have saved Ariane V, the documentation and testing 
benefits of Eiffel's assertions would benefit many, many software 
projects.

-- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-12  0:00                                     ` Jon S Anthony
  1997-08-13  0:00                                       ` Ted Velkoff
@ 1997-08-13  0:00                                       ` Don Harrison
  1997-08-13  0:00                                         ` Jon S Anthony
  1997-08-13  0:00                                         ` Samuel Mize
  1 sibling, 2 replies; 255+ messages in thread
From: Don Harrison @ 1997-08-13  0:00 UTC (permalink / raw)



Jon S Anthony wrote:

:In article <EEsF5y.F5H@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:
:
:> it can be expected to do a better job of it. If Ada protected types allow 
:> the designer to explicitly leave objects unlocked (which doesn't appear to 
:> be supported by the Ada95 Rationale), then they are more permissive but 
:> in a detrimental way, IMO.
:
:You're not twigging this stuff.  

Possibly. 

:The objects can be unlocked for
:_read_ access, but never for any update access.  

Care to give an example?


:> :can requeue requests, 
:> 
:> IMO, the situations in which you would use "requeue" are better handled by 
:> designing differently - perhaps by using an additional class. If anything,
:> "requeue" probably encourages poor design.
:
:Requeue is specifically there to eliminate in principle any timing
:errors.  The way this works is somewhat subtle, so maybe you are not
:twigging this either.

On re-reading the Ada95 Rationale, I think I have a handle on this now.
(See my response to Ken.)


:> simulating the surrounding environment. Then, any assertions
:> assuming Ariane 4 inputs would be violated (as would the Ada
:> constraint_error). In general, the extra checking afforded by DBC
:> would mean more bugs would be identified than if it wasn't
:> used. (Yes, I know there is no difference wrt the one that caused
:> the failure.)
:
:The problem with this is the simple observation of "why would the
:assertions be there in the first place?"  After all, in the particular
:case at hand, they were _intentionally_ removed.  And with perfectly
:sound engineering principles in mind.  Assertions in the code _cannot_
:capture the constraints presumed for the context of use.  This has to
:come from somewhere else (external documentation, "instructions",
:"warrenty notes", whatever.)  The odd thing here is that this point
:should be "blindingly obvious", to use one of your phrases.

Yes, I agree it is. I'm talking about (an aspect of) how I think it *ought* to
be done, not how it *was* done. 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-07  0:00                                     ` Ken Garlington
@ 1997-08-13  0:00                                       ` Don Harrison
  1997-08-13  0:00                                         ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-13  0:00 UTC (permalink / raw)



Ken asked for evidence that SCOOP supports thread-level timing.

Ken Garlington wrote:

:I hadn't realized we were dealing in terms of a "higher truth" that
:doesn't require argument or evidence. 

The evidence is in OOSC-2. I would leave it at that but I'll give an example 
because I may have been responsible for confusing you. :(  Sorry if that's the
case.

I might have said that locking in SCOOP occurs at the object level. Anyone 
familiar with protected types would immediately assume this means objects are 
locked one-at-a-time (whenever they're called). SCOOP is fundamentally different 
in that groups of objects are locked together. As I'll explain later, this 
is an important distinction.

Why are they collectively locked?
Answer: So that processing can be performed under known conditions without 
  interference from other threads (helping to avoid race conditions). Also,
  so that we know up-front that we have all the resources we needed (helping
  to avoid deadlock).

When are they collectively locked? 
Answer: When they're supplied as parameters to an operation.

What if they're not supplied as parameters?
Answer: They always *are* (in the case of concurrent (separate) objects. 
  In the case of sequential (non-separate) object, we don't care because 
  we know they're local to the calling thread.

See the example below..

:> :Futhermore, here is a counter-argument to writing timing assertions
:> :at the object level:
:> :
:> :Using letters to denote objects, let's build a thread. The notation
:> :x{object}y means that the object is executed between x and y times.
:> :The arrows indicate that one object is executed before another object
:> :in the sequence. (For simplicity, we'll neglect objects calling
:> :objects).
:> :
:> :Thread: A -> B -> 1{C}4 -> D
:> :
:> :The max time for this thread is: A + B + 4*C + D, right?
:> :
:> :No!
:> :
:> :It also includes:
:> : 1. the entry/exit code for each object (4 times that, for C),
:> : 2. the time to start and stop the thread itself
:> : 3. Any time between object invocations "stolen" by other threads.
:> 
:> 3) doesn't apply to SCOOP because all objects are locked.
:
:(3) represents the time _in between_ object invocations. 

You might code your example in pseudo-SCOOP:

Assuming separate (allocated to different threads) entities

  my_p: separate P
  my_q: separate Q
  my_r: separate R
  my_s: separate S

and operation

  do_something (p: separate P; q: separate Q; r: separate R; s: separate S) is
  local
    start_time: time
    duration: ...
  do
    start_time := time_now
    p.a
    q.b
    loop (4 times)
      r.c
    end
    s.d
    duration := time_now - start_time
    ...
  end

the call

  do_something (my_p, my_q, my_r, my_s)

will do the required actions and measure the elapsed time.

Note that all four objects are locked for the block between "do" and "end".
This means that there is no intervening time between calls to them and there
is no opportunity for any other threads to jump in and make a mess of things.

Note that this offers more protection than Ada protected objects which are 
only locked on single object basis. As you will see later, this also removes 
the need for a "requeue" statement.


:If you are saying that a thread (a series of object invocations) cannot be
:interrupted at _any point_, then that pretty much eliminates
:concurrency, doesn't it?

No, it just means it's more controlled (and safer). There is a complementary 
library mechanism called "express messages" which allows pre-emption of threads.


:I have a feeling that we're just not communicating on this issue. 

True.

:My experience is in real-time systems, and I think I'm just not
:properly conveying the issues involved in developing those systems.

Likewise.

:> :If you start the measurement before the call to A, and stop it
:> :after the call to D, you only have to worry about #2 above
:> :(which is usually fixed). If you do the measurement at the object
:> :level, all three will skew your results.
:> 
:> Not true. If you really want to get a clue on this, I suggest you get hold
:> of OOSC-2 and read the chapter on concurrency.

Sorry, Ken. I was a bit rude here.



:Ken Garlington wrote (about Ada protected types):

::can requeue requests, 

I wrote:

:IMO, the situations in which you would use "requeue" are better handled by 
:designing differently - perhaps by using an additional class. 

Sorry, this is wrong. The problem in Ada which "requeue" is designed to deal 
with doesn't arise in SCOOP because successive calls to the same separate 
object are atomic. That is, the object doesn't get unlocked between calls.
For example,

  do_something (a: separate A) is
  do
    a.do_x
    a.do_y
  end

does exactly what we expect. There is no need for do_x to "requeue" do_y.
IMO, "requeue" is a wokaround to a design flaw in Ada's concurrency - namely 
locking at the object level. Further, it's a *deficient* workaround because 
supplier objects are forced to do things (do_y) that should be the 
responsibility of clients (do_something).

:If anything, "requeue" probably encourages poor design.

.. as I've just explained.



Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                       ` Ted Velkoff
@ 1997-08-13  0:00                                         ` Jon S Anthony
  1997-08-13  0:00                                         ` Ken Garlington
  1 sibling, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-08-13  0:00 UTC (permalink / raw)



In article <33F133D7.71AC@erols.com> Ted Velkoff <velkoff@erols.com> writes:

> Jon S Anthony wrote:
> > 
> > The problem with this is the simple observation of "why would the
> > assertions be there in the first place?"  After all, in the particular
> > case at hand, they were _intentionally_ removed.  And with perfectly
> > sound engineering principles in mind.  Assertions in the code _cannot_
> > capture the constraints presumed for the context of use.  This has to
> > come from somewhere else (external documentation, "instructions",
> > "warrenty notes", whatever.) [...]
> > 
> 
> There is an important distinction between including/removing assertions 
> and monitoring/not monitoring them during execution.  One of the 
> principal benefits of Eiffel is the fact that assertions remain in the 
> code (where programmers will see them) even if they are not tested 
> dynamically (this is controlled by a compile-time switch).  Whether or 
> not this would have saved Ariane V, the documentation and testing 
> benefits of Eiffel's assertions would benefit many, many software 
> projects.

Nobody is saying that assertions are somehow bad or even that they are
somehow not particularly effective _when used where they can actually
say something about what it is you are trying to check_.  Assertions
in the code cannot address the constraints imposed by the intended
context of use.  That's a global multi system variability issue.

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                       ` Don Harrison
  1997-08-13  0:00                                         ` Jon S Anthony
@ 1997-08-13  0:00                                         ` Samuel Mize
  1997-08-13  0:00                                           ` Robert A Duff
  1 sibling, 1 reply; 255+ messages in thread
From: Samuel Mize @ 1997-08-13  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Jon S Anthony wrote:
[about Ada protected objects]
> :The objects can be unlocked for
> :_read_ access, but never for any update access.
> 
> Care to give an example?

"Locked" is a common term, but its application to Ada is not
defined by the Ada Reference Manual (ARM), so it may be
unclear or accidentally misleading.

The ARM refers to protected operations being "blocked" if they
cannot "acquire" the "execution resource associated with a
protected object" (ARM 9.4(18)).

"Protected procedures provide exclusive read-write access to ...
a protected object; protected functions provide concurrent
read-only access" (ARM 9.5.1 (1)).  For one protected object,
"a new protected action is not started ... while another ...
is underway, unless both actions are the result of a call on
a protected function." (ARM 9.5.1(4)).

In other words, a protected object can have functions and
procedures (treating entries are a type of procedure).  A
procedure can't start while a function is executing, but a
function can; nothing else can start while a procedure is
executing.

During an operation on the object that can change its value
(a procedure), you can't "unlock" the object for others to
read.  However, an operation that can't change the object's
value (a function) does NOT acquire an exclusive lock, just
a read lock.

Sam Mize




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                       ` Don Harrison
@ 1997-08-13  0:00                                         ` Jon S Anthony
  1997-08-15  0:00                                           ` Don Harrison
  1997-08-13  0:00                                         ` Samuel Mize
  1 sibling, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-08-13  0:00 UTC (permalink / raw)



In article <EEuDC9.MtH@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> :The problem with this is the simple observation of "why would the
> :assertions be there in the first place?"  After all, in the particular
> :case at hand, they were _intentionally_ removed.  And with perfectly
> :sound engineering principles in mind.  Assertions in the code _cannot_
> :capture the constraints presumed for the context of use.  This has to
> :come from somewhere else (external documentation, "instructions",
> :"warrenty notes", whatever.)  The odd thing here is that this point
> :should be "blindingly obvious", to use one of your phrases.
> 
> Yes, I agree it is. I'm talking about (an aspect of) how I think it
> *ought* to be done, not how it *was* done.

The point is, the significant aspect of your "how it ought to be done"
is _impossible_.  Not just wasn't done, not just impractical, but
outright impossible.

However, you and the E-Jihad have succeeded in wearing me down.  I
give up.  The whole thing is pointless.

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                         ` Ken Garlington
  1997-08-13  0:00                                           ` Ted Velkoff
@ 1997-08-14  0:00                                           ` Nick Leaton
  1997-08-16  0:00                                             ` Robert Dewar
  1997-08-18  0:00                                             ` Joachim Durchholz
  1 sibling, 2 replies; 255+ messages in thread
From: Nick Leaton @ 1997-08-14  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> 
> Ted Velkoff wrote:
> >
> > There is an important distinction between including/removing assertions
> > and monitoring/not monitoring them during execution.  One of the
> > principal benefits of Eiffel is the fact that assertions remain in the
> > code (where programmers will see them) even if they are not tested
> > dynamically (this is controlled by a compile-time switch).  Whether or
> > not this would have saved Ariane V, the documentation and testing
> > benefits of Eiffel's assertions would benefit many, many software
> > projects.
> 
> This is certainly reasonable. However, once the execution capabilities
> are removed, it seems fair to ask what Eiffel provides that comments
> (available in most langauges) don't provide. If there is not a
> significant
> difference, then Eiffel would not be any better (in this context) than
> any other language, so long as the DBC principles were followed.

There is one advantage. If your assertions are compiled, they must
conform to a set restricted style. Comments are, on the other hand very
free form. I think it is reasonable to say that the compiled
assertions are less likely to be ambiguous than if they are just
a comment. They are more likely to be correct if they have been executed
and tested.

-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                           ` Ted Velkoff
@ 1997-08-14  0:00                                             ` Matt Austern
  1997-08-14  0:00                                               ` Ted Velkoff
  1997-08-15  0:00                                             ` Ken Garlington
  1 sibling, 1 reply; 255+ messages in thread
From: Matt Austern @ 1997-08-14  0:00 UTC (permalink / raw)



Ted Velkoff <velkoff@erols.com> writes:

> Meanwhile at home I write software in Eiffel, where assertions are built 
> into the language.  In Eiffel, all I do is Step 1: write the 
> pre/post-conditions and invariants.  I don't need to do Step 2 (keep 
> spec and body in synch) since in Eiffel, the spec (properly speaking, 
> the short form) is automatically generated by tools.  Step 3, (coding 
> the assertion tests, handling failures, providing useful diagnostics) is 
> provided automatically by the environment.  Furthermore, the three flaws 
> are eliminated: 1) with a compile-time switch I can turn off monitoring 
> (I don't have to go through and "comment out" reams of code); 2) it's 
> easy to monitor post-conditions, since this is provided by the tools 
> (caveat - this is useful for testing and integration; postcondition 
> monitoring necessarily incurs a performance penalty); 3) mentioned 
> above, there is no spec/body redundancy to be managed by the programmer.

Have preconditions and postconditions been extended in recent versions
of Eiffel?  I haven't yet read the second editon of Eiffel: The
Language yet, and I haven't used Eiffel for a year or so.  When I last
did, though, there were a number of restrictions on them.  I note
that, because of those restrictions, many of the interesting
preconditions and postconditions in ETL itself were written as
comments rather than as executable code.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                           ` Robert A Duff
@ 1997-08-14  0:00                                             ` Jon S Anthony
  1997-08-15  0:00                                             ` Don Harrison
  1 sibling, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-08-14  0:00 UTC (permalink / raw)



In article <EEvAnx.281@world.std.com> bobduff@world.std.com (Robert A Duff) writes:

> The Ada folks seem to be missing Don's earlier point, which is that in
> Eiffel you can lock a bunch of objects all at once, whereas in Ada, you

I don't think people are missing this point at all.

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-14  0:00                                             ` Matt Austern
@ 1997-08-14  0:00                                               ` Ted Velkoff
  1997-08-18  0:00                                                 ` Matt Austern
  0 siblings, 1 reply; 255+ messages in thread
From: Ted Velkoff @ 1997-08-14  0:00 UTC (permalink / raw)



Matt Austern wrote:
> 
> Have preconditions and postconditions been extended in recent versions
> of Eiffel?  I haven't yet read the second editon of Eiffel: The
> Language yet, and I haven't used Eiffel for a year or so.  When I last
> did, though, there were a number of restrictions on them.  I note
> that, because of those restrictions, many of the interesting
> preconditions and postconditions in ETL itself were written as
> comments rather than as executable code.

You are correct that there are (still) limitations to the expressiveness 
of assertions.  In particular, one cannot write executable quantified 
expressions, e.g. "for_all x in y it_holds x.item > 0".  This would be a 
valuable capability indeed, since one could, for instance, compile 
(that is, type check) an analysis or design, including its assertions.

In my view, the fact that some kinds of assertions are not executable 
does not lesson the value of Eiffel.  I would hazard a guess that at 
least 75% to 80% of the assertions one would want to write are of the 
form that are supported.  For me, that is still a big gain.

-- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                         ` Ken Garlington
@ 1997-08-14  0:00                                           ` Don Harrison
  1997-08-15  0:00                                             ` Ken Garlington
                                                               ` (2 more replies)
  0 siblings, 3 replies; 255+ messages in thread
From: Don Harrison @ 1997-08-14  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> Ken asked for evidence that SCOOP supports thread-level timing.
:> 
:> Ken Garlington wrote:
:> 
:> Why are they collectively locked?
:> Answer: So that processing can be performed under known conditions without
:>   interference from other threads (helping to avoid race conditions). Also,
:>   so that we know up-front that we have all the resources we needed (helping
:>   to avoid deadlock).
:
:What happens if the resource is unavailable (already locked by a
:lower-priority thread, for example)?

The caller blocks until the resource is available. There are actually no 
lower-priority threads - all threads are the same priority and their requests 
are queued impartially. Where timing is not an issue this gives you what you 
want because you get a kind of statistical "prioritisation". What I mean is 
that threads will automatically get serviced by a supplier object in proportion 
to the number of calls they make to it. In this situation, you don't care 
which threads are serviced first. You only care about whether there is enough
processing capacity and if there isn't enough, you have a problem regardless 
of what queueing scheme is used.

Where timing *is* an issue, you use express messages. This mechanism allows 
threads to dynamically change their "priority" relative to other threads.
This mechanism should only be used where it's critical to transfer control.
There are two parties involved - the holder and the challenger - and they "duel"
for control of a resource. Duels either result in a transfer of control or 
the challenger waiting till the holder finishes with the resource.

Threads change their relative "priority" through calls to library routines:

  Holder: 
    - retain (the default) makes the holder resist a challenge.
    - yield makes the holder willing to yield.

  Challenger: 
    - wait_turn (the default) makes the challenger willing to wait.
    - demand makes the challenger mount a challenge and commit suicide if resisted.
    - insist makes the challenger mount a challenge but wait if resisted.

The outcome of duels is summarised in the following table:

                                              Challenger
                   -----------------------------------------------------------------
                  |    [wait_turn]              demand               insist
        ----------|-----------------------------------------------------------------
Holder | [retain] | [Challenger waits]  Exception in Challenger  Challenger waits
       | yield    | Challenger waits    Exception in holder      Exception in holder


Notes:

1) Defaults are exclosed in square brackets. Note the default behaviour of 
   the challenger waiting.

2) This simple dual priority scheme can be embellished to offer multiple 
   relative "priorities".

Examples of use:

  - A thread which absolutely must execute (possibly driven by a timer) can
    issue a challenge for a resource.
  - A thread performing a long IO operation can offer to yield to a more 
    critical thread.


:It seems to me that, locking _all_ objects involved in an operation (without
:regard to whether they guard a sensitive resource, such as a data store
:that can be written by multiple threads) means that the latencies associated
:with the threads goes up dramatically, particularly if the locking is
:transitive.

I was also concerned about this issue initially but came to the conclusion 
that objects would be locked for just as long as they (safely) need to be.
Where it's important to release a frequently used shared resource quickly, 
various design strategies can be applied to minimise locking.
 
:Priority inversion would also seem to be much more likely.

Can you explain what you mean by this?


:Ada has a different approach. Consider a fairly simple case of a value that
:is read by some tasks, written by others. Clearly, if a thread is writing
:a value, it should start and complete that operation before any other
:access to that resource. Similarly, any attempt to read the resource should
:start and complete before any write to the resource begins. 

Agree.

:However,
:a read by a low-priority task can be suspended to permit a higher-priority
:task to read the same resouirce (assuming no side-effects of the read).
:As I understand it, you would prohibit this benign "interference." Thus,
:the high-priority task (which may run much more frequently than the
:low-priority task) is unnecessarily delayed, potentially causing it
:to meet it's deadline.

No. In this case, the reads could occur concurrently (due to optimisations).

:You claimed that the compiler could optimize the timing properties of
:the system; I would be interested in seeing such a compiler..

I don't think it would be too hard. The compiler just has to verify that 
queries (functions) are truly benign and implement two types of locks 
- read and write. This is yet another reason to strictly enforce side-effect-
free functions.


:It wouldn't catch the extry/exit time of do_something, but
:that's not a big deal. 

At a higher level call, perhaps..

:I see you've missed the original
:part of the thread. The poster suggested writing 
:assertions (post-conditions) on P, Q, R, and S as the
:way to do this, which (as I said) won't work effectively.
:Your approach is at the thread level, not the object
:level, which is the way I would have done it as well.
:So, in fact, we agree that the original post is in
:error (I assume).

Probably - can't remember what was said.


:> will do the required actions and measure the elapsed time.
:> 
:> Note that all four objects are locked for the block between "do" and "end".
:> This means that there is no intervening time between calls to them and there
:> is no opportunity for any other threads to jump in and make a mess of things.
:
:Just out of curiosity, can the "local" section make reference to these
:objects?

Can't recall (and couldn't see from a quick glance at OOSC-2) but do know 
you would be limited in what you could do. For example, a local separate 
object couldn't be the target of a call. Why do you ask? 


:Also, how is "do_something" attached to a hardware event? 

Not sure, but probably via a call to a library routine.


:> Note that this offers more protection than Ada protected objects which are
:> only locked on single object basis. As you will see later, this also removes
:> the need for a "requeue" statement.
:
:True. However, you pay a pretty terrible price for this protection, as
:far as I can tell. I can see several systems which literally could not
:be implemented under these rules.

They would likely be designed differently, though, by paying more attention
to locking issues. 


:> :If you are saying that a thread (a series of object invocations) cannot be
:> :interrupted at _any point_, then that pretty much eliminates
:> :concurrency, doesn't it?
:> 
:> No, it just means it's more controlled (and safer). There is a complementary
:> library mechanism called "express messages" which allows pre-emption of threads.
:
:Perhaps this "express messages" is the backdoor which I have to believe
:a real system would need.

Correct.

:Correct me if I'm wrong, but no other thread can run while do_something is
:executing? 

On a single processor, yes. On a multiple processor, no.

:Or are you saying it can be interrupted, just that no other thread
:can access the objects referenced in the parameter list (or any objects
:referenced in _their_ parameter lists? )?

Correct.


Have run out of time. Will respond to the rest tomorrow.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                           ` Ken Garlington
@ 1997-08-15  0:00                                             ` Paul Johnson
  1997-08-15  0:00                                               ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Paul Johnson @ 1997-08-15  0:00 UTC (permalink / raw)



In article <33F25AA5.49ED@flash.net>, kennieg@flash.net says...
>
>Paul Johnson wrote:

>> The whole point is to document the interface, and then check
>> the documentation for correctness.
>
>Against what? All you have is the code and the assertions created as
>part
>of the code. Checking them against each other determines internal
>consistency between the two, but that's all.

Its a pretty big "all".  Such an inconsistency points to an error
either in the documentation or the code.  Then you can go and figure
out which one is wrong.

>Based on the studies I've
>seen, most errors aren't to pure internal inconsistencies at the code
>level.

I have some difficulty parsing that.  I take it you mean that most
errors in software are not due to inconsistencies in the code.  So what?
Most development systems do not include automatic checking of the
documentation.  This is design-level stuff, not code level.

>It's difficult to explain a software methodology to someone who only
>sees one step: coding.

Please don't talk down to me: you'll only miss.

Try thinking of Eiffel as a software engineering notation, rather than
just a programming language.  Its features allow the code to 
capture information about the analysis, design and implementation.  This
information is kept in one place, in one format and hence can be
checked for consistency.

Paul.

-- 
Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
+44 1245 242244         +-----------+-----------------------------------------+
Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
Home: <Paul@treetop.demon.co.uk>    | standards, all different.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                           ` Ted Velkoff
  1997-08-14  0:00                                             ` Matt Austern
@ 1997-08-15  0:00                                             ` Ken Garlington
  1997-08-16  0:00                                               ` Ted Velkoff
  1 sibling, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-08-15  0:00 UTC (permalink / raw)



Ted Velkoff wrote:
> 
> Ken Garlington responded to an earlier post of mine:
> >
> > This is certainly reasonable. However, once the execution capabilities
> > are removed, it seems fair to ask what Eiffel provides that comments
> > (available in most langauges) don't provide. If there is not a
> > significant
> > difference, then Eiffel would not be any better (in this context) than
> > any other language, so long as the DBC principles were followed.
> >
> 
> In my experience, there is a significant difference.  I will not presume
> to make a scientific claim; rather I will offer a personal, anecdotal
> example.
> 
> About two years ago, I built a modest enhancement to a system which
> amounted to 4K lines each of Ada and C++.  In the package specs and
> module headers I included preconditions, postconditions and invariants
> as comments.  In the Ada bodies, I wrote if-then-else clauses to test
> preconditions (violations led to a chain of exceptions raised out to
> the main program).  In the C++ implementations, I included conditionally
> compiled calls to the assert macro (which does a core dump and spits out
> a file and line number) for preconditions and trivial
> postconditions.

I think you're anwering the wrong mail :)

Please re-read the first paragraph. The discussion is about the value of
Eiffel assertions if they are _always_ turned off, vs. comments.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-14  0:00                                           ` Don Harrison
  1997-08-15  0:00                                             ` Ken Garlington
  1997-08-15  0:00                                             ` Don Harrison
@ 1997-08-15  0:00                                             ` Lee Webber
  1997-08-19  0:00                                               ` Don Harrison
  2 siblings, 1 reply; 255+ messages in thread
From: Lee Webber @ 1997-08-15  0:00 UTC (permalink / raw)



On Thu, 14 Aug 1997 07:38:08 GMT, donh@syd.csa.com.au (Don Harrison)
wrote:

>Ken Garlington wrote:
>
>:Don Harrison wrote:
     ...
>:It seems to me that, locking _all_ objects involved in an operation (without
>:regard to whether they guard a sensitive resource, such as a data store
>:that can be written by multiple threads) means that the latencies associated
>:with the threads goes up dramatically, particularly if the locking is
>:transitive.
>
>I was also concerned about this issue initially but came to the conclusion 
>that objects would be locked for just as long as they (safely) need to be.
>Where it's important to release a frequently used shared resource quickly, 
>various design strategies can be applied to minimise locking.
  ^^^^^^^^^^^^^^^^^^^

I would be interested in your expanding on this.  In particular, how
would you implement this in SCOOP:

        gain exclusive access to A
           perform time-consuming work using A and local resources
        gain exclusive access to A and B jointly
           perform work using A, B and local resources computed above
        release A, retain B
           perform time-consuming work using B and local resources
              computed above
        release access to B

making sure that neither A nor B is held when it is not needed.  (You
may assume that all competing processes attempt to acquire A and B in
the order above -- otherwise there is no solution other than the
trivial that avoids deadlock.)




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-14  0:00                                           ` Don Harrison
@ 1997-08-15  0:00                                             ` Ken Garlington
  1997-08-19  0:00                                               ` Don Harrison
  1997-08-15  0:00                                             ` Don Harrison
  1997-08-15  0:00                                             ` Lee Webber
  2 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-08-15  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> The caller blocks until the resource is available. There are actually no
> lower-priority threads - all threads are the same priority and their requests
> are queued impartially. Where timing is not an issue this gives you what you
> want because you get a kind of statistical "prioritisation". What I mean is
> that threads will automatically get serviced by a supplier object in proportion
> to the number of calls they make to it. In this situation, you don't care
> which threads are serviced first. You only care about whether there is enough
> processing capacity and if there isn't enough, you have a problem regardless
> of what queueing scheme is used.

That's true iff the threads are all the same priority. I've yet to work
on a
real system where this is the case, so this doesn't really help much...

> 
> Where timing *is* an issue, you use express messages. This mechanism allows
> threads to dynamically change their "priority" relative to other threads.
> This mechanism should only be used where it's critical to transfer control.
> There are two parties involved - the holder and the challenger - and they "duel"
> for control of a resource. Duels either result in a transfer of control or
> the challenger waiting till the holder finishes with the resource.

Does this mean that each thread has to know it's relative priority to
all other
threads (more to the point, thread interfaces)? That would be a serious
maintainability issue, I would think. You might want to look at some of
the real-time projet examples in the ADARTS courseware, for example.

>   - A thread which absolutely must execute (possibly driven by a timer) can
>     issue a challenge for a resource.

If, while another thread is operating, it cannot be interrrupted (as
your
previous note said, a thread cannot be interrupted even between object
calls),
then how does the other thread begin execution to issue the challenge?

> I was also concerned about this issue initially but came to the conclusion
> that objects would be locked for just as long as they (safely) need to be.
> Where it's important to release a frequently used shared resource quickly,
> various design strategies can be applied to minimise locking.

Don't these "design strategies" cause the same uncertainly that you said
you
didn't want? For example, if a lower-priority thread agrees to give up
control
of an object to a higher-priority thread, then race conditions are
possible
if the threads are not designed properly.

This seems counter-intuitive. Consider the simple protected object
discussed
earlier with the Read and Write operations. It would seem that the
object
itself, with its internal knowledge of how Read and Write works, would
be
the better place to control when blocking needs to occur. In order for
the
threads that use this object to decide the outcome of their "duel",
don't
they have to know the internal operation of the object -- an object
contract
violation?

> 
> :Priority inversion would also seem to be much more likely.
> 
> Can you explain what you mean by this?

Priority inversion? When a low prioity task seizes a high prioity
resource,
it effectively operates at the priority of the seized resource. If a
high
priority task then attempts to seize the resource, it is effectively
blocked
by the lower priority task -- priority inversion. However, since you can
in
fact have a thread interrupt another thread (has to happen, otherwise
there
is no "dueling"), and since the higher-priority thread can seize the
lower
one, I assume this can be avoided. However, it also opens the door to
both mutual exclusion and deadlock.

> :Ada has a different approach. Consider a fairly simple case of a value that
> :is read by some tasks, written by others. Clearly, if a thread is writing
> :a value, it should start and complete that operation before any other
> :access to that resource. Similarly, any attempt to read the resource should
> :start and complete before any write to the resource begins.
> 
> Agree.
> 
> :However,
> :a read by a low-priority task can be suspended to permit a higher-priority
> :task to read the same resouirce (assuming no side-effects of the read).
> :As I understand it, you would prohibit this benign "interference." Thus,
> :the high-priority task (which may run much more frequently than the
> :low-priority task) is unnecessarily delayed, potentially causing it
> :to meet it's deadline.
> 
> No. In this case, the reads could occur concurrently (due to optimisations).

Describe the general-purpose algorithm used to determince this by a
compiler.
If you can, you'll put a lot of system architects out of business!

Has such an algorithm been implemented yet? I would like to test this
wonderful
tool!

> :You claimed that the compiler could optimize the timing properties of
> :the system; I would be interested in seeing such a compiler..
> 
> I don't think it would be too hard. The compiler just has to verify that
> queries (functions) are truly benign 

Define "benign"! For example, is a read of a memory location "benign"?
Maybe not, if it's memory-mapped I/O. Some devices, for example, don't
take
kindly to starting a read and being interrupted in the middle to do a
new
read.

You may not think it's too hard, but I suspect you haven't encountered
many of these real-life systems.

> and implement two types of locks
> - read and write. This is yet another reason to strictly enforce side-effect-
> free functions.
> 
> :It wouldn't catch the extry/exit time of do_something, but
> :that's not a big deal.
> 
> At a higher level call, perhaps..
> 
> :I see you've missed the original
> :part of the thread. The poster suggested writing
> :assertions (post-conditions) on P, Q, R, and S as the
> :way to do this, which (as I said) won't work effectively.
> :Your approach is at the thread level, not the object
> :level, which is the way I would have done it as well.
> :So, in fact, we agree that the original post is in
> :error (I assume).
> 
> Probably - can't remember what was said.
> 
> :> will do the required actions and measure the elapsed time.
> :>
> :> Note that all four objects are locked for the block between "do" and "end".
> :> This means that there is no intervening time between calls to them and there
> :> is no opportunity for any other threads to jump in and make a mess of things.
> :
> :Just out of curiosity, can the "local" section make reference to these
> :objects?
> 
> Can't recall (and couldn't see from a quick glance at OOSC-2) but do know
> you would be limited in what you could do. For example, a local separate
> object couldn't be the target of a call. Why do you ask?

Because you said that they were locked between the "do" and "end". If
they
can be referenced in the local section, but are not locked, this would
seem
to be a Bad Thing.

> :Also, how is "do_something" attached to a hardware event?
> 
> Not sure, but probably via a call to a library routine.
> 
> :> Note that this offers more protection than Ada protected objects which are
> :> only locked on single object basis. As you will see later, this also removes
> :> the need for a "requeue" statement.
> :
> :True. However, you pay a pretty terrible price for this protection, as
> :far as I can tell. I can see several systems which literally could not
> :be implemented under these rules.
> 
> They would likely be designed differently, though, by paying more attention
> to locking issues.

It's difficult to communicate to someone without the experience, but
it's much like asking someone to do a periodic task without reference to
any timer, clock, etc. It's theoretically possible, but in practice such
an implementation is pretty much impossible.

> 
> :> :If you are saying that a thread (a series of object invocations) cannot be
> :> :interrupted at _any point_, then that pretty much eliminates
> :> :concurrency, doesn't it?
> :>
> :> No, it just means it's more controlled (and safer). There is a complementary
> :> library mechanism called "express messages" which allows pre-emption of threads.
> :
> :Perhaps this "express messages" is the backdoor which I have to believe
> :a real system would need.
> 
> Correct.
> 
> :Correct me if I'm wrong, but no other thread can run while do_something is
> :executing?
> 
> On a single processor, yes. 
> On a multiple processor, no.
> 
> :Or are you saying it can be interrupted, just that no other thread
> :can access the objects referenced in the parameter list (or any objects
> :referenced in _their_ parameter lists? )?
> 
> Correct.

OK, this makes more sense. However, it does mean that my original
comment
is correct -- assertions at the object level cannot be added up to
form the thread time, since threads can be interrupted. That's all
I needed to know.

> 
> Have run out of time. Will respond to the rest tomorrow.
> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                             ` Don Harrison
@ 1997-08-15  0:00                                               ` Ken Garlington
  1997-08-16  0:00                                                 ` Jon S Anthony
  1997-08-19  0:00                                                 ` Don Harrison
  0 siblings, 2 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-15  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> ::Or are you saying it can be interrupted, just that no other thread
> ::can access the objects referenced in the parameter list (or any objects
> ::referenced in _their_ parameter lists? )?
> :
> :Correct.
> 
> I need to clarify this. Unless the default duelling status of the objects
> involved changes as a result of calls to class CONCURRENCY (retain, yield,
> wait_turn, demand, insist), a thread will not be interrupted and (in theory)
> no other thread can access the objects in the parameter list of the operation
> being called.

This makes no sense, given your last post. If no other thread can
interrupt,
how is a duel initiated?

> 
> On protected types:
> 
> Ken Garlington wrote:
> 
> :> ::can requeue requests,
> :>
> :> I wrote:
> :> ... The problem in Ada which "requeue" is designed to deal
> :> with doesn't arise in SCOOP because successive calls to the same separate
> :> object are atomic. That is, the object doesn't get unlocked between calls.
> 
> This means that, under SCOOP, locking is operation-based rather than
> object-based. Protected types, in contrast, have object-based locking. This
> means that a calling thread issuing two consecutive calls to a protected
> object cannot be guaranteed that no other thread will update the protected
> object between the calls.
> 
> If I understand correctly, requeues are a means of getting around this problem
> by allowing the callee (the protected object)  to issue extra calls (on behalf
> of the calling thread) while it is still locked. I think this scheme is
> deficient for a couple of reasons:
> 
> 1) It doesn't fix the underlying problem - the lack of atomicity inherent in
>    object-based locking. As such, it's a workaround rather than a mechanism
>    that should exist in its own right.
> 
> 2) It's undesirable from a modelling perspective:
> 
>    a) It's incorrect for a caller to be making calls to itself *on behalf
>       of the caller*.
> 
>    b) It introduces undesirable interdependencies between entries - for example,
>       the blocking abstraction on P. 9-16 of the Ada95 Rationale.
> 
>       Under SCOOP, inherently autonomous operations remain autonomous in
>       accordance with sound design (read "OO principles").

Actually, it promotes OO principles, since the reasons for the requeue
are
often due to the internal implementation of the protected object, and
thus
can be hidden from the caller.

> One thing I'm curious about is where the requeued call gets placed on the
> entry queue. I guess it must be placed on the head, rather than the tail,
> for this to work. Is that the case?

All queues are generally FIFO. Note that the requeued call doesn't have
to
be on the _same_ queue.

"The entry queuing policy controls selection among queued calls both
for task and protected entry queues. The default entry queuing policy
is to select calls on a given entry queue in order of arrival. If calls
from two or more queues are simultaneously eligible for selection, the
default entry queuing policy does not specify which queue is serviced
first.
Other entry queuing policies can be specified by pragmas (see D.4)."

> 
> :True. However, the question still stands: What happens if a thread attempts to
> :access a locked (or otherwise unavailable) resource?
> 
> It gets queued in the queue of callers for that object (one queue per object).
> Out of interest, is there one queue per protected object or one queue per entry?

One per entry (which is what you want, if you want the timing behavior
to be
different based on the operation/entry called).

> 
> :I can use requeue in these situations;
> 
> Sorry, don't see what you mean. As far as I can see, requeue is used by the
> thread that has control of the protected object, not a thread that's trying
> to get hold of it.

No, any entry can be requeued. Furthermore, it's not up to the caller or
callee,
it's up to the protected object:

"A requeue_statement can be used to complete an accept_statement or
entry_body,
while redirecting the corresponding entry call to a new (or the same)
entry
queue. Such a requeue can be performed with or without allowing an
intermediate cancellation of the call, due to an abort or the expiration
of a delay."

"A requeue_statement shall be within a callable construct that is either
an
entry_body or an accept_statement, and this construct shall be the
innermost
enclosing body or callable construct."

Again, the internal timing/sequence requirements can be hidden within
the
object. It makes the decisions based on its internal state, not the
caller
or callee. This is what you want a server task to be able to do, of
course.

> 
> what do you do?
> 
> The controlling thread doesn't have to worry about it because it retains control
> of the separate object even when individual calls to it have completed. The
> separate object only gets unlocked when the calling operation itself completes.
> 
> :> For example,
> :>
> :>   do_something (a: separate A) is
> :>   do
> :>     a.do_x
> :>     a.do_y
> :>   end
> :>
> :> does exactly what we expect. There is no need for do_x to "requeue" do_y.
> :
> :That's not how requeue works, as I understand it. The issue is more: you
> :attempt to do a.do_x, and someone else has already seized the resource, or
> :there is some other time-based reason why a.do_x is unavailable.
> 
> What you've described sounds more like the mechanism for queuing calls. Requeue
> is something different, as I understand it.

Well, I'm new to Ada 95, so you may be right. However, take a peek at

  http://www.adahome.com/rm95/rm9x-09-05-04.html#1

or the quotes from it above.

> 
> :> IMO, "requeue" is a wokaround to a design flaw in Ada's concurrency - namely
> :> locking at the object level. Further, it's a *deficient* workaround because
> :> supplier objects are forced to do things (do_y) that should be the
> :> responsibility of clients (do_something).
> :
> :It depends. A "requeue" may be needed because of the state of the
> :object, and may not be related to the state of do_something.
> 
> In that case, do_somthing need only test the state of the separate object
> and take whatever action is necessary - calling another operation in it,
> for example.

It's that "test the state" that bothers me. Why do I need to expose the
internal state of the object? Seems somewhat non-OO to me. It also means
that the object can't enforce it's own timing policies -- it has to
trust
the caller to do the right thing.

> 
>    do_something (a: separate A) is
>    do
>      a.do_x
>      if a.some_condition then
>        a.do_y
>      end
>    end
> 
> :> :If anything, "requeue" probably encourages poor design.
> :>
> :> .. as I've just explained.
> :
> :Sorry, don't see it.
> :
> :I think you would need to apply SCOOP to some fairly complex
> :real-time systems to see the problems I'm discussing.
> 
> I think I've addressed all the issues you were concerned about. From a
> theoretical standpoint, SCOOP should work and should be scaleable. Of course,
> it will be reassuring to have the theory vindicated by seeing it applied
> successfully to a significant-sized project.

Agreed. I think I would be much more convinced once this optimizing
compiler
hits the streets, and people start looking at the effort to define all
of
the dueling relationships.

> 
> :So long as all the objects have short lifetimes, and no priority issues
> :are around, I would assume it seems to work fine for simple systems.
> 
> I think it will be fine for *any* size system. Obviously, it will require a
> different design approach to that used with Ada because of some fundamental
> differences. These differences make it both more restrictive (in reliability-
> enhancing ways) and less restrictive (in ways that enhance reuse and modelling
> integrity).

The design approaches I describe didn't come with Ada. They've been
around
since assembly days. The same issues are described in real-time courses
regardless of implementation language.

It would be interested to take some examples from these courses, such as
the
HAS Buoy, Cruise Control, and ATD/CWM case studies from the ADARTS
material,
and have them coded in SCOOP and executed.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                             ` Paul Johnson
@ 1997-08-15  0:00                                               ` Ken Garlington
  1997-08-18  0:00                                                 ` Joachim Durchholz
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-08-15  0:00 UTC (permalink / raw)



Paul Johnson wrote:
> 
> In article <33F25AA5.49ED@flash.net>, kennieg@flash.net says...
> >
> >Paul Johnson wrote:
> 
> >> The whole point is to document the interface, and then check
> >> the documentation for correctness.
> >
> >Against what? All you have is the code and the assertions created as
> >part
> >of the code. Checking them against each other determines internal
> >consistency between the two, but that's all.
> 
> Its a pretty big "all".  Such an inconsistency points to an error
> either in the documentation or the code.  Then you can go and figure
> out which one is wrong.
> 
> >Based on the studies I've
> >seen, most errors aren't to pure internal inconsistencies at the code
> >level.
> 
> I have some difficulty parsing that.  I take it you mean that most
> errors in software are not due to inconsistencies in the code.  So what?

So, (a) that's where the difficult part lies and (b) it means a
methodology
that focuses on code inconsistency is not working the difficult part.

> Most development systems do not include automatic checking of the
> documentation.  This is design-level stuff, not code level.

That's why automated checking should not be relied upon to find
the hard errors. 

> 
> >It's difficult to explain a software methodology to someone who only
> >sees one step: coding.
> 
> Please don't talk down to me: you'll only miss.
> 
> Try thinking of Eiffel as a software engineering notation, rather than
> just a programming language.  Its features allow the code to
> capture information about the analysis, design and implementation.  This
> information is kept in one place, in one format and hence can be
> checked for consistency.

Again: You need to have experience in systems analysis and requirements
capture to understand that the hard stuff is not readily expressible
in code. This isn't talking down to you, it's just that you don't
apparently have experience in this area. This issue is described further
in:

  http://www.flash.net/~kennieg/ariane.html

> 
> Paul.
> 
> --
> Paul Johnson            | GEC-Marconi Ltd is not responsible for my opinions. |
> +44 1245 242244         +-----------+-----------------------------------------+
> Work: <paul.johnson@gecm.com>       | You are lost in a twisty maze of little
> Home: <Paul@treetop.demon.co.uk>    | standards, all different.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                         ` Jon S Anthony
@ 1997-08-15  0:00                                           ` Don Harrison
  1997-08-16  0:00                                             ` Jon S Anthony
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-15  0:00 UTC (permalink / raw)



Jon S Anthony wrote:

:In article <EEuDC9.MtH@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:
:
:> :The problem with this is the simple observation of "why would the
:> :assertions be there in the first place?"  After all, in the particular
:> :case at hand, they were _intentionally_ removed.  And with perfectly
:> :sound engineering principles in mind.  Assertions in the code _cannot_
:> :capture the constraints presumed for the context of use.  This has to
:> :come from somewhere else (external documentation, "instructions",
:> :"warrenty notes", whatever.)  The odd thing here is that this point
:> :should be "blindingly obvious", to use one of your phrases.
:> 
:> Yes, I agree it is. I'm talking about (an aspect of) how I think it
:> *ought* to be done, not how it *was* done.
:
:The point is, the significant aspect of your "how it ought to be done"
:is _impossible_.  Not just wasn't done, not just impractical, but
:outright impossible.

But, perhaps, nowhere near as impossible as acheiving a mutual understanding 
as to what would and wouldn't have helped?  :)

:However, you and the E-Jihad have succeeded in wearing me down.  I
:give up.  The whole thing is pointless.

How disappointing.  :)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-13  0:00                                           ` Robert A Duff
  1997-08-14  0:00                                             ` Jon S Anthony
@ 1997-08-15  0:00                                             ` Don Harrison
  1997-08-16  0:00                                               ` Ken Garlington
  1 sibling, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-15  0:00 UTC (permalink / raw)



Bob Duff wrote:

:To answer Don's question: protected objects can be locked for read-only
:access, or for read-write access.  Read-only access does not exclude
:other readers.
:
:The Ada folks seem to be missing Don's earlier point, which is that in
:Eiffel you can lock a bunch of objects all at once, whereas in Ada, you
:lock just one object at a time (that is, a protected operation X.Op(Y, Z)
:locks X, but not Y and Z (in Ada).

Thanks (on both counts).


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-14  0:00                                           ` Don Harrison
  1997-08-15  0:00                                             ` Ken Garlington
@ 1997-08-15  0:00                                             ` Don Harrison
  1997-08-15  0:00                                               ` Ken Garlington
  1997-08-15  0:00                                             ` Lee Webber
  2 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-15  0:00 UTC (permalink / raw)



I wrote:

::>... There is a complementary
::> library mechanism called "express messages" which allows pre-emption of threads.
::
::Perhaps this "express messages" is the backdoor which I have to believe
::a real system would need.
:
:Correct.
:
::Correct me if I'm wrong, but no other thread can run while do_something is
::executing? 
:
:On a single processor, yes. On a multiple processor, no.
:
::Or are you saying it can be interrupted, just that no other thread
::can access the objects referenced in the parameter list (or any objects
::referenced in _their_ parameter lists? )?
:
:Correct.

I need to clarify this. Unless the default duelling status of the objects 
involved changes as a result of calls to class CONCURRENCY (retain, yield,
wait_turn, demand, insist), a thread will not be interrupted and (in theory)
no other thread can access the objects in the parameter list of the operation
being called.


On protected types:

Ken Garlington wrote:
 
:> ::can requeue requests,
:> 
:> I wrote:
:> ... The problem in Ada which "requeue" is designed to deal
:> with doesn't arise in SCOOP because successive calls to the same separate
:> object are atomic. That is, the object doesn't get unlocked between calls.

This means that, under SCOOP, locking is operation-based rather than 
object-based. Protected types, in contrast, have object-based locking. This 
means that a calling thread issuing two consecutive calls to a protected 
object cannot be guaranteed that no other thread will update the protected 
object between the calls. 

If I understand correctly, requeues are a means of getting around this problem
by allowing the callee (the protected object)  to issue extra calls (on behalf 
of the calling thread) while it is still locked. I think this scheme is 
deficient for a couple of reasons:

1) It doesn't fix the underlying problem - the lack of atomicity inherent in
   object-based locking. As such, it's a workaround rather than a mechanism 
   that should exist in its own right.

2) It's undesirable from a modelling perspective:

   a) It's incorrect for a caller to be making calls to itself *on behalf 
      of the caller*.

   b) It introduces undesirable interdependencies between entries - for example,
      the blocking abstraction on P. 9-16 of the Ada95 Rationale. 

      Under SCOOP, inherently autonomous operations remain autonomous in 
      accordance with sound design (read "OO principles").

One thing I'm curious about is where the requeued call gets placed on the 
entry queue. I guess it must be placed on the head, rather than the tail, 
for this to work. Is that the case?


:True. However, the question still stands: What happens if a thread attempts to
:access a locked (or otherwise unavailable) resource? 

It gets queued in the queue of callers for that object (one queue per object).
Out of interest, is there one queue per protected object or one queue per entry?

:I can use requeue in these situations; 

Sorry, don't see what you mean. As far as I can see, requeue is used by the
thread that has control of the protected object, not a thread that's trying 
to get hold of it.

what do you do?

The controlling thread doesn't have to worry about it because it retains control
of the separate object even when individual calls to it have completed. The 
separate object only gets unlocked when the calling operation itself completes.


:> For example,
:> 
:>   do_something (a: separate A) is
:>   do
:>     a.do_x
:>     a.do_y
:>   end
:> 
:> does exactly what we expect. There is no need for do_x to "requeue" do_y.
:
:That's not how requeue works, as I understand it. The issue is more: you
:attempt to do a.do_x, and someone else has already seized the resource, or
:there is some other time-based reason why a.do_x is unavailable.

What you've described sounds more like the mechanism for queuing calls. Requeue 
is something different, as I understand it.


:> IMO, "requeue" is a wokaround to a design flaw in Ada's concurrency - namely
:> locking at the object level. Further, it's a *deficient* workaround because
:> supplier objects are forced to do things (do_y) that should be the
:> responsibility of clients (do_something).
:
:It depends. A "requeue" may be needed because of the state of the
:object, and may not be related to the state of do_something.

In that case, do_somthing need only test the state of the separate object 
and take whatever action is necessary - calling another operation in it,
for example.

   do_something (a: separate A) is
   do
     a.do_x
     if a.some_condition then
       a.do_y
     end
   end


:> :If anything, "requeue" probably encourages poor design.
:> 
:> .. as I've just explained.
:
:Sorry, don't see it.
:
:I think you would need to apply SCOOP to some fairly complex
:real-time systems to see the problems I'm discussing. 

I think I've addressed all the issues you were concerned about. From a 
theoretical standpoint, SCOOP should work and should be scaleable. Of course, 
it will be reassuring to have the theory vindicated by seeing it applied 
successfully to a significant-sized project.

:So long as all the objects have short lifetimes, and no priority issues
:are around, I would assume it seems to work fine for simple systems.

I think it will be fine for *any* size system. Obviously, it will require a 
different design approach to that used with Ada because of some fundamental 
differences. These differences make it both more restrictive (in reliability-
enhancing ways) and less restrictive (in ways that enhance reuse and modelling 
integrity).


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                             ` Ken Garlington
@ 1997-08-16  0:00                                               ` Ted Velkoff
  1997-08-16  0:00                                                 ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Ted Velkoff @ 1997-08-16  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> 
> Ted Velkoff wrote:
> >
> > Ken Garlington responded to an earlier post of mine:
> > >
> > > This is certainly reasonable. However, once the execution capabilities
> > > are removed, it seems fair to ask what Eiffel provides that comments
> > > (available in most langauges) don't provide. If there is not a
> > > significant
> > > difference, then Eiffel would not be any better (in this context) than
> > > any other language, so long as the DBC principles were followed.
> > >
> >
> > In my experience, there is a significant difference.  I will not presume
> > to make a scientific claim; rather I will offer a personal, anecdotal
> > example.
> >[ Example followed here...]
> 
> I think you're anwering the wrong mail :)

I'll try again.
> 
> Please re-read the first paragraph. The discussion is about the value of
> Eiffel assertions if they are _always_ turned off, vs. comments.

To begin with, by "_always_ turned off", I assume what is meant is 
"turned off during execution of a delivered system", not "turned off 
during execution of a delivered system and during its entire development 
phase".

If an Eiffel executable is built with assertion monitoring turned off, 
it is indeed no different than, say, an Ada executable built using 
pragma Suppress (Range_Check, for example).  This would be appropriate 
during the final stages of testing a product, for Factory/Site 
Acceptance Test, and delivery to a customer.

For the bulk of development, from design through code, unit and 
integration testing, one would certainly want to monitor assertions (in 
Eiffel) or Range_Checks, for instance (in Ada).  Clearly these sorts of 
compile- and run-time checks are far more powerful than mere comments 
and aid in earlier detection and correction of errors.  I say that using 
Eiffel is superior to using another language with commented assertions 
because Eiffel makes it so easy and cost-effective to write AND test 
Boolean-valued assertions during the bulk of the development life-cycle.

-- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-16  0:00                                               ` Ted Velkoff
@ 1997-08-16  0:00                                                 ` Ken Garlington
  1997-08-16  0:00                                                   ` Jon S Anthony
  1997-08-18  0:00                                                   ` Ted Velkoff
  0 siblings, 2 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-16  0:00 UTC (permalink / raw)



Ted Velkoff wrote:
> 
> Ken Garlington wrote:
> >
> > Ted Velkoff wrote:
> > >
> > > Ken Garlington responded to an earlier post of mine:
> > > >
> > > > This is certainly reasonable. However, once the execution capabilities
> > > > are removed, it seems fair to ask what Eiffel provides that comments
> > > > (available in most langauges) don't provide. If there is not a
> > > > significant
> > > > difference, then Eiffel would not be any better (in this context) than
> > > > any other language, so long as the DBC principles were followed.
> > > >
> > >
> > > In my experience, there is a significant difference.  I will not presume
> > > to make a scientific claim; rather I will offer a personal, anecdotal
> > > example.
> > >[ Example followed here...]
> >
> > I think you're anwering the wrong mail :)
> 
> I'll try again.
> >
> > Please re-read the first paragraph. The discussion is about the value of
> > Eiffel assertions if they are _always_ turned off, vs. comments.
> 
> To begin with, by "_always_ turned off", I assume what is meant is
> "turned off during execution of a delivered system", not "turned off
> during execution of a delivered system and during its entire development
> phase".

Not how the original argument was phrased. However if you want to argue
the merits of turning them on during development and then off for
released
code, see section 3.2.2 of

  http://www.flash.net/~kennieg/ariane.html

for my rebuttal.

> If an Eiffel executable is built with assertion monitoring turned off,
> it is indeed no different than, say, an Ada executable built using
> pragma Suppress (Range_Check, for example).  This would be appropriate
> during the final stages of testing a product, for Factory/Site
> Acceptance Test, and delivery to a customer.
> 
> For the bulk of development, from design through code, unit and
> integration testing, one would certainly want to monitor assertions (in
> Eiffel) or Range_Checks, for instance (in Ada).  Clearly these sorts of
> compile- and run-time checks are far more powerful than mere comments
> and aid in earlier detection and correction of errors.  I say that using
> Eiffel is superior to using another language with commented assertions
> because Eiffel makes it so easy and cost-effective to write AND test
> Boolean-valued assertions during the bulk of the development life-cycle.
> 
> -- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-14  0:00                                           ` Nick Leaton
@ 1997-08-16  0:00                                             ` Robert Dewar
  1997-08-18  0:00                                             ` Joachim Durchholz
  1 sibling, 0 replies; 255+ messages in thread
From: Robert Dewar @ 1997-08-16  0:00 UTC (permalink / raw)



Nick says

<<There is one advantage. If your assertions are compiled, they must
conform to a set restricted style. Comments are, on the other hand very
free form. I think it is reasonable to say that the compiled
assertions are less likely to be ambiguous than if they are just
a comment. They are more likely to be correct if they have been executed
and tested.>>


That is most definitely true, however, if you restrict assertions to
executable form, that is most certainly a fierce restriction, particularly
in languages like Ada and Eiffel whose expressive power is nowhere near
that of full set theory. 

It is perfectly reasonable to have assertions in comments that are impractical
to execute, or even to talk about infinite sets where the assertions are not
even conceptually computable.

I would not rule out the utility of such assertions, though there is always
considerable value in putting assertions (or specs of any kind) into 
executable form where possible.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                             ` Don Harrison
@ 1997-08-16  0:00                                               ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-16  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Bob Duff wrote:
> 
> :To answer Don's question: protected objects can be locked for read-only
> :access, or for read-write access.  Read-only access does not exclude
> :other readers.
> :
> :The Ada folks seem to be missing Don's earlier point, which is that in
> :Eiffel you can lock a bunch of objects all at once, whereas in Ada, you
> :lock just one object at a time (that is, a protected operation X.Op(Y, Z)
> :locks X, but not Y and Z (in Ada).
> 
> Thanks (on both counts).

Actually, this was the source of my concern (automatic locking of all
objects
accessed, vs. per-operation locking). However, since this locking is not
exactly "automatic" (the "dueling" concept can be used to overcome it),
my
concern now is more in terms of

  1. having this part of the system design spread out amongst the
threads,
     instead of a more object-oriented style of containing it within the
     protected object, and

  2. the compiler complexity required to optimize "benign" calls to
avoid
     locks on a given operation in the first place.

Don doesn't see the first issue as a design problem, and doesn't see the
second issue as a difficult compiler problem. We'll have to wait for
implementations to appear to determine who's right, I guess.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-16  0:00                                                 ` Ken Garlington
@ 1997-08-16  0:00                                                   ` Jon S Anthony
  1997-08-16  0:00                                                     ` Ken Garlington
  1997-08-18  0:00                                                     ` Ted Velkoff
  1997-08-18  0:00                                                   ` Ted Velkoff
  1 sibling, 2 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-08-16  0:00 UTC (permalink / raw)



In article <33F5D274.30C4@flash.net> Ken Garlington <kennieg@flash.net> writes:

> > To begin with, by "_always_ turned off", I assume what is meant is
> > "turned off during execution of a delivered system", not "turned off
> > during execution of a delivered system and during its entire development
> > phase".
> 
> Not how the original argument was phrased. However if you want to argue
> the merits of turning them on during development and then off for
> released
> code, see section 3.2.2 of
> 
>   http://www.flash.net/~kennieg/ariane.html
> 
> for my rebuttal.

You know, it would really help if most of the people trying to "argue"
some contrary point here, would read this paper and understand it
before going off.  Most of the counter arguments pretty much simply
evaporate at that point.

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                           ` Don Harrison
@ 1997-08-16  0:00                                             ` Jon S Anthony
  0 siblings, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-08-16  0:00 UTC (permalink / raw)



In article <EExM7r.BLA@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> :The point is, the significant aspect of your "how it ought to be done"
> :is _impossible_.  Not just wasn't done, not just impractical, but
> :outright impossible.
> 
> But, perhaps, nowhere near as impossible as acheiving a mutual
> understanding as to what would and wouldn't have helped?  :)

Unlikely.  At least such an understanding is _logically_ possible (in
the formal sense of the term).

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                               ` Ken Garlington
@ 1997-08-16  0:00                                                 ` Jon S Anthony
  1997-08-19  0:00                                                 ` Don Harrison
  1 sibling, 0 replies; 255+ messages in thread
From: Jon S Anthony @ 1997-08-16  0:00 UTC (permalink / raw)



In article <33F526A9.23E5@flash.net> Ken Garlington <kennieg@flash.net> writes:

> > :That's not how requeue works, as I understand it. The issue is more: you
> > :attempt to do a.do_x, and someone else has already seized the resource, or
> > :there is some other time-based reason why a.do_x is unavailable.
> > 
> > What you've described sounds more like the mechanism for queuing
> > calls. Requeue is something different, as I understand it.
> 
> Well, I'm new to Ada 95, so you may be right.

From what I can see, you have it pretty much right.  Ergo, Don has it...

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-16  0:00                                                   ` Jon S Anthony
@ 1997-08-16  0:00                                                     ` Ken Garlington
  1997-08-18  0:00                                                     ` Ted Velkoff
  1 sibling, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-16  0:00 UTC (permalink / raw)



Jon S Anthony wrote:
> 
> In article <33F5D274.30C4@flash.net> Ken Garlington <kennieg@flash.net> writes:
> 
> > > To begin with, by "_always_ turned off", I assume what is meant is
> > > "turned off during execution of a delivered system", not "turned off
> > > during execution of a delivered system and during its entire development
> > > phase".
> >
> > Not how the original argument was phrased. However if you want to argue
> > the merits of turning them on during development and then off for
> > released
> > code, see section 3.2.2 of
> >
> >   http://www.flash.net/~kennieg/ariane.html
> >
> > for my rebuttal.
> 
> You know, it would really help if most of the people trying to "argue"
> some contrary point here, would read this paper and understand it
> before going off.  Most of the counter arguments pretty much simply
> evaporate at that point.

Thanks for the vote of confidence, although I don't think the paper's
_that_ strong :)

Perhaps it's because there's not enough people who (a) use Eiffel,
(b) use the Internet, (c) care about this discussion, and (d) have
experience in Ariane 5-type systems, but I have been disappointed that
there's been very little movement of the discussion from my arguments,
as included in the paper. Most of the responses have either been

1. Repetitions of the "party line" (no specific discussion of any of
the arguments in the paper), or

2. Emotional reactions to the idea that Eiffel might not be the best
solution.

Neither has been particularly interesting. The SCOOP thread has been
useful, but it doesn't really relate to the Ariane 5 discussion. I am
particularly disappointed that the example in the Web version of the
Eiffel paper hasn't been corrected. Mr. Meyer and others may
disagree with my opinions, but I would think they would at least
correct obvious errors of fact once identified.

> /Jon
> --
> Jon Anthony
> OMI, Belmont, MA 02178, 617.484.3383
> "Nightmares - Ha!  The way my life's been going lately,
>  Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-16  0:00                                                 ` Ken Garlington
  1997-08-16  0:00                                                   ` Jon S Anthony
@ 1997-08-18  0:00                                                   ` Ted Velkoff
  1997-08-19  0:00                                                     ` Ken Garlington
  1 sibling, 1 reply; 255+ messages in thread
From: Ted Velkoff @ 1997-08-18  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> 
> Ted Velkoff wrote:
> > To begin with, by "_always_ turned off", I assume what is meant is
> > "turned off during execution of a delivered system", not "turned off
> > during execution of a delivered system and during its entire development
> > phase".[...]
> 
> Not how the original argument was phrased. However if you want to argue
> the merits of turning them on during development and then off for
> released
> code, see section 3.2.2 of
> 
>   http://www.flash.net/~kennieg/ariane.html
> 
> for my rebuttal.
> 

All the points made in section 3.2.2 are valid (meeting deadlines, 
issues in regression testing, limits to development resources).  But is 
it really never appropriate to monitor assertions at any time in the 
development life-cycle?

Forget about Eiffel for a moment, and consider Ada.  I'm starting to 
think that the approach being advocated would suggest using "pragma 
Supress" throughout the entire development cycle, starting with unit 
test.  Without ever having tried to do things that way, it seems on the 
surface that it would be harder to detect and correct bugs in the early 
going.  Isn't there some amount of run-time checking that is appropriate 
during development even if it is turned off later?

-- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-16  0:00                                                   ` Jon S Anthony
  1997-08-16  0:00                                                     ` Ken Garlington
@ 1997-08-18  0:00                                                     ` Ted Velkoff
  1 sibling, 0 replies; 255+ messages in thread
From: Ted Velkoff @ 1997-08-18  0:00 UTC (permalink / raw)



I wrote:
> > > To begin with, by "_always_ turned off", I assume what is meant is
> > > "turned off during execution of a delivered system", not "turned off
> > > during execution of a delivered system and during its entire development
> > > phase".

Ken Garlington wrote:
> > Not how the original argument was phrased. However if you want to argue
> > the merits of turning them on during development and then off for
> > released
> > code, see section 3.2.2 of
> >
> >   http://www.flash.net/~kennieg/ariane.html
> >
> > for my rebuttal.

Jon S Anthony wrote:
> You know, it would really help if most of the people trying to "argue"
> some contrary point here, would read this paper and understand it
> before going off.  Most of the counter arguments pretty much simply
> evaporate at that point.
> 

For the record, I have read Bertrand Meyer's article on Ariane V; the 
European Space Agency's report; and at least a week ago, Ken 
Garlington's paper.  I have endeavored to the best of my ability to 
understand all of them.

-- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-14  0:00                                           ` Nick Leaton
  1997-08-16  0:00                                             ` Robert Dewar
@ 1997-08-18  0:00                                             ` Joachim Durchholz
  1997-08-19  0:00                                               ` Ken Garlington
  1 sibling, 1 reply; 255+ messages in thread
From: Joachim Durchholz @ 1997-08-18  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> This is certainly reasonable. However, once the execution capabilities
> are removed, it seems fair to ask what Eiffel provides that comments
> (available in most langauges) don't provide. If there is not a
> significant
> difference, then Eiffel would not be any better (in this context) than
> any other language, so long as the DBC principles were followed.

Even if the assertions were ignored by the compiler there is a
difference.
There is a tool called "flat" that examines a class and its ancestors
and produces an equivalent class without inheritance. In particular, it
collects all assertions from all ancestors and lists them with the final
routine. (There is even an option that gives just the signatures and
assertions, leaving out the routine bodies.)
This gives us full documentation about every routine of every class,
without having to refer to ancestor classes. So even if assertions are
comments, these comments get included in the flat form of any descendant
class.

> There is one advantage. If your assertions are compiled, they must
> conform to a set restricted style. Comments are, on the other hand
> very
> free form.

Actually it's not restricted style. It is just that comments that are in
certain parts of the class text (namely, the assertion sections)
automatically gets included in the flat form of descendants.

Regards,
Joachim
-- 
Please don't send unsolicited ads.






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                               ` Ken Garlington
@ 1997-08-18  0:00                                                 ` Joachim Durchholz
  1997-08-19  0:00                                                   ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Joachim Durchholz @ 1997-08-18  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> > ...most
> > errors in software are not due to inconsistencies in the code.
> 
> So, (a) that's where the difficult part lies

Agreed.

> and (b) it means a
> methodology
> that focuses on code inconsistency is not working the difficult part.

The issue is that DBC allows to integrate code and code documentation
better. It is possible to write top-level abstract classes that just
encapsulate a few assertions; there is no need to duplicate these
assertions in other documents, at Eiffel (at this level) is easy to read
even for a non-programmer.

> > Try thinking of Eiffel as a software engineering notation, rather
> > than just a programming language.  Its features allow the code to
> > capture information about the analysis, design and implementation.
> > This information is kept in one place, in one format and hence can
> > be checked for consistency.
> 
> Again: You need to have experience in systems analysis and
> requirements
> capture to understand that the hard stuff is not readily expressible
> in code.

Eiffel assertions are *not* code. They are specifications for code.
 Some of these specifications happen to be checkable at run-time, so
they take the form of executable expressions instead of comments, but
that's a secondary issue.

Regards,
Joachim
-- 
Please don't send unsolicited ads.






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-14  0:00                                               ` Ted Velkoff
@ 1997-08-18  0:00                                                 ` Matt Austern
  1997-08-20  0:00                                                   ` Joachim Durchholz
  0 siblings, 1 reply; 255+ messages in thread
From: Matt Austern @ 1997-08-18  0:00 UTC (permalink / raw)



Ted Velkoff <velkoff@erols.com> writes:

> Matt Austern wrote:
> > 
> > Have preconditions and postconditions been extended in recent versions
> > of Eiffel?  I haven't yet read the second editon of Eiffel: The
> > Language yet, and I haven't used Eiffel for a year or so.  When I last
> > did, though, there were a number of restrictions on them.  I note
> > that, because of those restrictions, many of the interesting
> > preconditions and postconditions in ETL itself were written as
> > comments rather than as executable code.
> 
> You are correct that there are (still) limitations to the expressiveness 
> of assertions.  In particular, one cannot write executable quantified 
> expressions, e.g. "for_all x in y it_holds x.item > 0".  This would be a 
> valuable capability indeed, since one could, for instance, compile 
> (that is, type check) an analysis or design, including its assertions.
> 
> In my view, the fact that some kinds of assertions are not executable 
> does not lesson the value of Eiffel.  I would hazard a guess that at 
> least 75% to 80% of the assertions one would want to write are of the 
> form that are supported.  For me, that is still a big gain.

That hasn't been my experience: my experience, when I did use Eiffel,
was that most of the interesting preconditions, postconditions, and
invariants tended to be complicated enough that I couldn't express
them within the language itself.

For example, what's the postcondition for a function that sorts a
range?  Three postconditions, of course: the range is sorted, the
range has the same number of elements as it did before, and the new
range is a permutation of the old range. (Depending on the sorting
algorithm, you might also have a postcondition that guarantees
stability of equivalent elements.) It's the last one that's a problem;
I never did figure out how to write a postcondition like that in
Eiffel, and I as far as I know it isn't possible.

In every language, it's certainly important to document carefully what
a function requires and what it guarantees to do.  Eiffel is similar
to all other languages in that many of these requirements and
guarantees have to live in the documentation rather than in the code.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-12  0:00                                         ` Mark A Biggar
@ 1997-08-19  0:00                                           ` Robert Dewar
  1997-08-19  0:00                                             ` Bertrand Meyer
                                                               ` (3 more replies)
  0 siblings, 4 replies; 255+ messages in thread
From: Robert Dewar @ 1997-08-19  0:00 UTC (permalink / raw)



Mark says

<<Sure, even if assertions are required by the language syntax,
you can always just use the assertion "true" :-).
You can't even make using the assertion "true" illegal as there are
cases where the assertion "true" is exactly the correct assertion to
use; for example, using "true" as a precondition for a method documents the
fact that it has NO enviromential requirements at all. (E.G. a random
number routine or the Unix exit() call).  And, what is the postcondition
for printf()?>>

As for the last question, this is just the tip of the iceburg. Of course it
is not the case that all requirements can be caught by pre and post conditions.

The idea of using pre and post conditions and assertions is very old. It
is useful but by no means applicable in all cases.

What should be the post condition after outputting an error message
from a compiler?

pragma Assert (programmer now understands what they did wrong);

You need a *really* clever language to test that one (well I suppose the
assertion routine executed at runtime could ask the programmer whether
he understood :-)





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                           ` Robert Dewar
@ 1997-08-19  0:00                                             ` Bertrand Meyer
  1997-08-19  0:00                                               ` Robert Dewar
  1997-08-19  0:00                                             ` Nick Leaton
                                                               ` (2 subsequent siblings)
  3 siblings, 1 reply; 255+ messages in thread
From: Bertrand Meyer @ 1997-08-19  0:00 UTC (permalink / raw)



Robert Dewar wrote:
 
> What should be the post condition after outputting an error message
> from a compiler?
> 
> pragma Assert (programmer now understands what they did wrong);
> 
> You need a *really* clever language to test that one
> (well I suppose the
> assertion routine executed at runtime could ask the programmer whether
> he understood :-)

You obviously must know better. The postcondition, if it
needs to be expressed, is something like "string XXX" [the
argument to the routine] "has been appended to the output".
With the proper model this is easy to express formally.


-- 
Bertrand Meyer, President, ISE Inc.
ISE Building, 2nd floor, 270 Storke Road, Goleta CA 93117
805-685-1006, fax 805-685-6869, <Bertrand.Meyer@eiffel.com>
http://www.eiffel.com, with instructions for free download
== ISE Eiffel 4: Eiffel from those who invented it ==




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                               ` Don Harrison
@ 1997-08-19  0:00                                                 ` Lee Webber
  0 siblings, 0 replies; 255+ messages in thread
From: Lee Webber @ 1997-08-19  0:00 UTC (permalink / raw)



On Tue, 19 Aug 1997 05:15:59 GMT, donh@syd.csa.com.au (Don Harrison)
wrote:

>Lee Webber wrote:
>
>:On Thu, 14 Aug 1997 07:38:08 GMT, donh@syd.csa.com.au (Don Harrison)
>:wrote:
>:>various design strategies can be applied to minimise locking.
>:  ^^^^^^^^^^^^^^^^^^^
>:
>:I would be interested in your expanding on this.  
>
>Looks like you think your bogometer's gone off again. :)

   In spades.

>:In particular, how would you implement this in SCOOP:
>:
>:        gain exclusive access to A
>:           perform time-consuming work using A and local resources
>:        gain exclusive access to A and B jointly
>:           perform work using A, B and local resources computed above
>:        release A, retain B
>:           perform time-consuming work using B and local resources
>:              computed above
>:        release access to B
>:
>:making sure that neither A nor B is held when it is not needed.  
>:(You may assume that all competing processes attempt to acquire A and B in
>:the order above -- otherwise there is no solution other than the
>:trivial that avoids deadlock.)
>
>The solution I'm thinking of would use:
>
>  - A staged approach in which intermediate data is computed.
>  - Express messages to yield to higher "priority" threads.
>  - A transaction-based approach to apply the results at the end on 
>    successful completion.
>
>I don't have the time to thrash out the details, but it should work and should 
>be safe.
>

I'll help you out, then.  It can't be done under SCOOP, **assuming as
I did in my problem that each stage uses the results from the previous
ones so you can't rearrange the code**.

The reason for this is simple: SCOOP ties acquisition and release of
objects to entry and exit from subroutines.  Therefore, the objects
will be obtained and released LIFO; you can't release objects other
than in the opposite order you acquired them.  This avoids deadlocks,
but at the possible cost of efficiency, as in my example.

Express messages don't help.  In order to seize control of an object
prematurely, you have to cause an exception in the context of the
holder, thus destroying that context.  (Checkpoints, and other such
hacks to allow resumption of processing at the same call level as the
exception, are treated here with the disdain they deserve.)
Attempting to rebuild the context involves reacquiring all the objects
and rolling back their states[1], thus making the efficiency problem
far worse.

Nor can you say that compiler optimization should allow the implicit
release of A as soon as the last feature call on it is complete.  The
problem here is that B may call A, and the client may be depending on
that call being synchronized with the calls it itself made -- a
guarantee made by SCOOP because the call is made in the scope of the
client's routine.  In order to make that guarantee, and unless you
want to do system flow analysis, you can't release any separate
objects until all of them have been used for the last time in the
routine.

[1] This raises a serious problem in the use of challenge/yield. It is
true that the exception in the separate object being invoked allows it
to restore its invariant.  But what its client probably wants to do is
to roll back the state of the object to what it was at the entry to
the routine -- and it doesn't own the object to tell it to do that.
(You could clone the object at the top of the routine just in case,
but cloning a separate object is not my idea of fun.)




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                             ` Bertrand Meyer
@ 1997-08-19  0:00                                               ` Robert Dewar
  1997-08-20  0:00                                                 ` Nick Leaton
  1997-08-20  0:00                                                 ` Lee Webber
  0 siblings, 2 replies; 255+ messages in thread
From: Robert Dewar @ 1997-08-19  0:00 UTC (permalink / raw)



Bertrand says

<<You obviously must know better. The postcondition, if it
needs to be expressed, is something like "string XXX" [the
argument to the routine] "has been appended to the output".
With the proper model this is easy to express formally.>>

But that's the whole point. Sure you can write a (pretty useless)
postcondition after 

print ("this is my useless error message");

to make sure you have added that string to the output file, but that tests
only whether your code is working, not whether it meets the specification,
which was to produce intelligible error messages. And I do not know what
you mean by "know better". If you mean do I know perfectly well that
postconditions cannot capture this kind of specification, yes, I know
that perfectly well -- many specifications and requirements cannot be
formalized in any useful manner.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-18  0:00                                             ` Joachim Durchholz
@ 1997-08-19  0:00                                               ` Ken Garlington
  1997-08-21  0:00                                                 ` Joachim Durchholz
  0 siblings, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-08-19  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:
> 
> Ken Garlington wrote:
> > This is certainly reasonable. However, once the execution capabilities
> > are removed, it seems fair to ask what Eiffel provides that comments
> > (available in most langauges) don't provide. If there is not a
> > significant
> > difference, then Eiffel would not be any better (in this context) than
> > any other language, so long as the DBC principles were followed.
> 
> Even if the assertions were ignored by the compiler there is a
> difference.
> There is a tool called "flat" that examines a class and its ancestors
> and produces an equivalent class without inheritance. In particular, it
> collects all assertions from all ancestors and lists them with the final
> routine. (There is even an option that gives just the signatures and
> assertions, leaving out the routine bodies.)
> This gives us full documentation about every routine of every class,
> without having to refer to ancestor classes. So even if assertions are
> comments, these comments get included in the flat form of any descendant
> class.

Can't such an extra-language tool be equally valid with comments in any
language (that has classes)?

> 
> > There is one advantage. If your assertions are compiled, they must
> > conform to a set restricted style. Comments are, on the other hand
> > very
> > free form.
> 
> Actually it's not restricted style. It is just that comments that are in
> certain parts of the class text (namely, the assertion sections)
> automatically gets included in the flat form of descendants.

This doesn't sound like Eiffel assertions, which are compiled.

> 
> Regards,
> Joachim
> --
> Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                               ` Ken Garlington
  1997-08-16  0:00                                                 ` Jon S Anthony
@ 1997-08-19  0:00                                                 ` Don Harrison
  1997-08-20  0:00                                                   ` Ken Garlington
  1 sibling, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-19  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:

:> On protected types:

:Actually, it promotes OO principles, since the reasons for the requeue are
:often due to the internal implementation of the protected object, and thus
:can be hidden from the caller.

Actually, on having another look, it probably *is* okay. The situation with
requeues seems roughly equivalent to the valid situation of a separate object 
executing one of its own operations. Reflexive queueing just seems a little 
weird. 

:> One thing I'm curious about is where the requeued call gets placed on the
:> entry queue. I guess it must be placed on the head, rather than the tail,
:> for this to work. Is that the case?
:
:All queues are generally FIFO. 

The tail, in other words.

:> Out of interest, is there one queue per protected object or one queue per entry?
:
:One per entry (which is what you want, if you want the timing behavior to be
:different based on the operation/entry called). 

So, how does the runtime system select which queue to take the next call from?
Is it arbitrary? ..or the one for the first declared entry? ..something else? 
I think entries, by default, should be serviced in the order in which they 
are received by the object - which implies object-based, rather than entry-based
queueing. This is how SCOOP works.


:.. any entry can be requeued. Furthermore, it's not up to the caller or callee,
:it's up to the protected object:

The callee *is* the protected object. What do you mean by callee?

:"A requeue_statement can be used to complete an accept_statement or entry_body,
:while redirecting the corresponding entry call to a new (or the same) entry
:queue. Such a requeue can be performed with or without allowing an
:intermediate cancellation of the call, due to an abort or the expiration
:of a delay."
:
:"A requeue_statement shall be within a callable construct that is either an
:entry_body or an accept_statement, and this construct shall be the innermost
:enclosing body or callable construct."
:
:Again, the internal timing/sequence requirements can be hidden within the
:object. It makes the decisions based on its internal state, ..

Seems okay.

:> :> IMO, "requeue" is a wokaround to a design flaw in Ada's concurrency - namely
:> :> locking at the object level. Further, it's a *deficient* workaround because
:> :> supplier objects are forced to do things (do_y) that should be the
:> :> responsibility of clients (do_something).

I think I probably misunderstood requeue's purpose here. The criticism of 
object-level locking reamains valid, though.


:> I think it will be fine for *any* size system. Obviously, it will require a
:> different design approach to that used with Ada because of some fundamental
:> differences. These differences make it both more restrictive (in reliability-
:> enhancing ways) and less restrictive (in ways that enhance reuse and modelling
:> integrity).
:
:The design approaches I describe didn't come with Ada. They've been around
:since assembly days. The same issues are described in real-time courses
:regardless of implementation language.
:
:It would be interested to take some examples from these courses, such as the
:HAS Buoy, Cruise Control, and ATD/CWM case studies from the ADARTS material,
:and have them coded in SCOOP and executed.

I agree - it would. If I get a chance, I'll take a look. Where are they?


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                             ` Lee Webber
@ 1997-08-19  0:00                                               ` Don Harrison
  1997-08-19  0:00                                                 ` Lee Webber
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-19  0:00 UTC (permalink / raw)



Lee Webber wrote:

:On Thu, 14 Aug 1997 07:38:08 GMT, donh@syd.csa.com.au (Don Harrison)
:wrote:
:
:>Ken Garlington wrote:
:>
:>:Don Harrison wrote:
:     ...
:>:It seems to me that, locking _all_ objects involved in an operation (without
:>:regard to whether they guard a sensitive resource, such as a data store
:>:that can be written by multiple threads) means that the latencies associated
:>:with the threads goes up dramatically, particularly if the locking is
:>:transitive.
:>
:>I was also concerned about this issue initially but came to the conclusion 
:>that objects would be locked for just as long as they (safely) need to be.
:>Where it's important to release a frequently used shared resource quickly, 
:>various design strategies can be applied to minimise locking.
:  ^^^^^^^^^^^^^^^^^^^
:
:I would be interested in your expanding on this.  

Looks like you think your bogometer's gone off again. :)

As I said in my response to Ken, they're not model-specific so I don't intend
being more specific.

:In particular, how would you implement this in SCOOP:
:
:        gain exclusive access to A
:           perform time-consuming work using A and local resources
:        gain exclusive access to A and B jointly
:           perform work using A, B and local resources computed above
:        release A, retain B
:           perform time-consuming work using B and local resources
:              computed above
:        release access to B
:
:making sure that neither A nor B is held when it is not needed.  
:(You may assume that all competing processes attempt to acquire A and B in
:the order above -- otherwise there is no solution other than the
:trivial that avoids deadlock.)

The solution I'm thinking of would use:

  - A staged approach in which intermediate data is computed.
  - Express messages to yield to higher "priority" threads.
  - A transaction-based approach to apply the results at the end on 
    successful completion.

I don't have the time to thrash out the details, but it should work and should 
be safe.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                           ` Robert Dewar
  1997-08-19  0:00                                             ` Bertrand Meyer
@ 1997-08-19  0:00                                             ` Nick Leaton
  1997-08-20  0:00                                             ` Ken Garlington
  1997-08-26  0:00                                             ` Richard A. O'Keefe
  3 siblings, 0 replies; 255+ messages in thread
From: Nick Leaton @ 1997-08-19  0:00 UTC (permalink / raw)



Robert Dewar wrote:
> 
> Mark says
> 
> <<Sure, even if assertions are required by the language syntax,
> you can always just use the assertion "true" :-).
> You can't even make using the assertion "true" illegal as there are
> cases where the assertion "true" is exactly the correct assertion to
> use; for example, using "true" as a precondition for a method documents the
> fact that it has NO enviromential requirements at all. (E.G. a random
> number routine or the Unix exit() call).  And, what is the postcondition
> for printf()?>>

Well if we take the Eiffel equivalents of printf, which are put_string,
put_integer ...

Basically put_<basic_type>. We can come up with sensible
postconditions.

Since we are writting to a file, and let us assume we have have a method
called file_position, which returns the position in the file.

For put_string we have

ensure
   old file_position + string.count = file_position

Since other routines are likely to use this to output the 
formatted values that means the other postconditions are
to be found in the formatting routines, where they 
belong.
 

> As for the last question, this is just the tip of the iceburg. Of course it
> is not the case that all requirements can be caught by pre and post conditions.

Agreed, but you should be breaking your requirements down into
smaller parts. 

Some are expressable, but wise to do. Membership of collections
is one, and specifying the postcondition of a sorted collection
is also not a wise postcondition to add.

If you were writing a library they may be a wise addition. Running them
in production code wouldn't be. It is too inefficient.

> The idea of using pre and post conditions and assertions is very old. It
> is useful but by no means applicable in all cases.
> 
> What should be the post condition after outputting an error message
> from a compiler?

> pragma Assert (programmer now understands what they did wrong);
> 
> You need a *really* clever language to test that one (well I suppose the
> assertion routine executed at runtime could ask the programmer whether
> he understood :-)

Please explain?

-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-18  0:00                                                   ` Ted Velkoff
@ 1997-08-19  0:00                                                     ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-19  0:00 UTC (permalink / raw)



Ted Velkoff wrote:
> 
> Forget about Eiffel for a moment, and consider Ada.  I'm starting to
> think that the approach being advocated would suggest using "pragma
> Supress" throughout the entire development cycle, starting with unit
> test.  Without ever having tried to do things that way, it seems on the
> surface that it would be harder to detect and correct bugs in the early
> going.  Isn't there some amount of run-time checking that is appropriate
> during development even if it is turned off later?

Only if you believe the benefits outweigh the penalties described in my
paper. I have delivered Ada systems where checking was never enabled,
and
where the "assertions" were checked using non-intrusive debugger
commands.
Of course, I still got the benefit of the static checking, which
(usually)
exists even if the run-time code is suppressed.

Note that, for non-safety-critical code written in Ada, I have delivered
the
code where the checks were left on in the production system. Again, this
is a very narrowly-focused domain we are discussing (which just happens
to
potentially include the Ariane 5 IRS).

> 
> -- Ted Velkoff




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-18  0:00                                                 ` Joachim Durchholz
@ 1997-08-19  0:00                                                   ` Ken Garlington
  1997-08-20  0:00                                                     ` Nick Leaton
  1997-08-21  0:00                                                     ` Joachim Durchholz
  0 siblings, 2 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-19  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:
> 
> Ken Garlington wrote:
> > > ...most
> > > errors in software are not due to inconsistencies in the code.
> >
> > So, (a) that's where the difficult part lies
> 
> Agreed.
> 
> > and (b) it means a
> > methodology
> > that focuses on code inconsistency is not working the difficult part.
> 
> The issue is that DBC allows to integrate code and code documentation
> better. It is possible to write top-level abstract classes that just
> encapsulate a few assertions; there is no need to duplicate these
> assertions in other documents, at Eiffel (at this level) is easy to read
> even for a non-programmer.

To demonstrate the problem, attempt to encode the critical Ariane 5
assumption as a "top-level abstract class." It is not directly
representable
as code, even as a "top-level" abstraction.

Said another way, could you write "War and Peace" as a "top-level"
abstraction?

> 
> > > Try thinking of Eiffel as a software engineering notation, rather
> > > than just a programming language.  Its features allow the code to
> > > capture information about the analysis, design and implementation.
> > > This information is kept in one place, in one format and hence can
> > > be checked for consistency.
> >
> > Again: You need to have experience in systems analysis and
> > requirements
> > capture to understand that the hard stuff is not readily expressible
> > in code.
> 
> Eiffel assertions are *not* code. They are specifications for code.
>  Some of these specifications happen to be checkable at run-time,

Read both of these statements carefully, several times.
That, coupled with the experiment I describe above, should demonstrate
the problem with your thinking.


> so
> they take the form of executable expressions instead of comments, but
> that's a secondary issue.
> 
> Regards,
> Joachim
> --
> Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-15  0:00                                             ` Ken Garlington
@ 1997-08-19  0:00                                               ` Don Harrison
  1997-08-19  0:00                                                 ` Lee Webber
  1997-08-20  0:00                                                 ` Ken Garlington
  0 siblings, 2 replies; 255+ messages in thread
From: Don Harrison @ 1997-08-19  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:
:> 
:> The caller blocks until the resource is available. There are actually no
:> lower-priority threads - all threads are the same priority and their requests
:> are queued impartially. Where timing is not an issue this gives you what you
:> want because you get a kind of statistical "prioritisation". What I mean is
:> that threads will automatically get serviced by a supplier object in proportion
:> to the number of calls they make to it. In this situation, you don't care
:> which threads are serviced first. You only care about whether there is enough
:> processing capacity and if there isn't enough, you have a problem regardless
:> of what queueing scheme is used.
:
:That's true iff the threads are all the same priority. I've yet to work
:on a real system where this is the case, so this doesn't really help much...

I think it depends what you use priorities for. If you use them for their 
intended purpose of ensuring threads meet their deadlines, then they only 
need be applied to threads that have deadlines.

The problem is many Ada developers misuse priorities to acheive correct 
synchronisation. Realtime systems that misuse priorities in this way tend 
(not surprisingly) to be very fragile, suffering from race conditions. 
The basic problem with using priorities for syncronisation is that you cannot 
guarantee correct behaviour. It is the *wrong* tool for the job. So, what's
the right tool? 

It's Design by Contract! Why? Because it allows you to express the necessary 
(*blocking*) conditions which are assumed to exist when a concurrent operation 
is executed. We recall that when those assumptions are violated in a sequential 
context, an exception is raised. In a concurrent context (ie. when the 
precondition involves a separate object), they assume synchronisation semantics. 
The caller blocks till another thread performs does something which causes the 
precondition to now be satisfied.

For example, an operation adding an item to a buffer:

  add_to_buffer (b: BUFFER; item: SOME_TYPE) is
  require not b.full
  do 
    b.add (item)
  end

Because b is non-separate (sequential), the precondition will fail if b is full.

  add_to_buffer (b: separate BUFFER; item: SOME_TYPE) is
  require not b.full
  do 
    b.add (item)
  end

Because b is separate (concurrent), the precondition will cause blocking until
another thread removes an item from the buffer (ie. b is not full).

Any Ada developer reading this should immediately recognise the similarity 
with guarded task entries and barriers on protected type entries. These 
mechanisms, then, are additional ways (apart from predefined assertions (think 
program_error etc.) and range-constrained subtypes) in which Ada provides some 
support for DBC. In fact, because guards and barriers are *general* boolean 
expressions, they are about as close as Ada gets to the generality of Eiifel's 
support for DBC.


Now, back to the priority issue..

Because, under SCOOP, you can apply such synchronisation assertions to any 
separate object, you are able to specify precisely the assumptions relevant 
to the operations offered by those objects and guarantee correct use.
This leaves priorities to be used for what their proper use - expressing 
relative importance of threads for facilitating timeliness. Consequently,
I expect a system implemented using SCOOP would have more "priority-less" 
threads.
 

:> Where timing *is* an issue, you use express messages. This mechanism allows
:> threads to dynamically change their "priority" relative to other threads.
:> This mechanism should only be used where it's critical to transfer control.
:> There are two parties involved - the holder and the challenger - and they "duel"
:> for control of a resource. Duels either result in a transfer of control or
:> the challenger waiting till the holder finishes with the resource.
:
:Does this mean that each thread has to know it's relative priority to all other
:threads (more to the point, thread interfaces)? 

No, but it does suggest the priority of a thread relative to all threads that 
it interacts with must be known. I'm not aware of any published information 
about how this is intended to work but imagine it could use abslolute priorities
(so implying relative ones):

  set_priority (p: PRIORITY) is ..        -- set absolute priority
  yield (p: PRIORITY) is ..               -- yield to priority p or greater
  etc.

:That would be a serious maintainability issue, I would think. 

Yes, if it were true - but it isn't.


:>   - A thread which absolutely must execute (possibly driven by a timer) can
:>     issue a challenge for a resource.
:
:If, while another thread is operating, it cannot be interrrupted (as your
:previous note said, a thread cannot be interrupted even between object calls),
:then how does the other thread begin execution to issue the challenge?

We're talking single processor here, of course (the issue doesn't arise with 
multi-processors). An executing thread will give up the processor to another 
thread if it blocks on a synchronisation condition (a precondition on a 
separate object). Expanding the buffer example above:

  x: separate BUFFER
  s: SOME_TYPE
  ...

  do_something is
  do
    ...
    add_to_buffer (x, s)
    ...
  end

do_something may block on the call to add_to_buffer (because the buffer is full)
causing another thread to run.


:> I was also concerned about this issue initially but came to the conclusion
:> that objects would be locked for just as long as they (safely) need to be.
:> Where it's important to release a frequently used shared resource quickly,
:> various design strategies can be applied to minimise locking.
:
:Don't these "design strategies" cause the same uncertainly that you said
:you didn't want? 

No. Also, these techniques can be applied to *any* concurrent system - they 
are not SCOOP-specific. Hence, they're not relevant to any discussion about 
the relative merits of different concurrency models. 


:For example, if a lower-priority thread agrees to give up control
:of an object to a higher-priority thread, then race conditions are possible
:if the threads are not designed properly.

Assertions would help you to design them properly and avoid such conditions. 
Also, invariants will guarantee that an object yielding in a duel will end 
up in a consistent state. 


:This seems counter-intuitive. Consider the simple protected object discussed
:earlier with the Read and Write operations. It would seem that the object
:itself, with its internal knowledge of how Read and Write works, would be
:the better place to control when blocking needs to occur. 

That *is* how blocking works under SCOOP. The operation of the supplier object 
contains the precondition, so the supplier determines the (synchronisation) 
contract.

:In order for the
:threads that use this object to decide the outcome of their "duel", don't
:they have to know the internal operation of the object -- an object contract
:violation?

No, only the object has to know (and how to restore its invariant - ie. how 
to return to a consistent state).


:> :Priority inversion would also seem to be much more likely.
:> 
:> Can you explain what you mean by this?
:
:Priority inversion? When a low prioity task seizes a high prioity resource,
:it effectively operates at the priority of the seized resource. If a high
:priority task then attempts to seize the resource, it is effectively blocked
:by the lower priority task -- priority inversion. However, since you can in
:fact have a thread interrupt another thread (has to happen, otherwise there
:is no "dueling"), and since the higher-priority thread can seize the lower
:one, I assume this can be avoided. 

Correct.

:However, it also opens the door to both mutual exclusion and deadlock.

..which are avoided (as in *any* concurrent system) by designing correctly.

:> No. In this case, the reads could occur concurrently (due to optimisations).
:
:Describe the general-purpose algorithm used to determince this by a compiler.

Ask Robert Dewar because that's what happens with protected types.  :)


:> :You claimed that the compiler could optimize the timing properties of
:> :the system; I would be interested in seeing such a compiler..
:> 
:> I don't think it would be too hard. The compiler just has to verify that
:> queries (functions) are truly benign 
:
:Define "benign"! For example, is a read of a memory location "benign"?
:Maybe not, if it's memory-mapped I/O. Some devices, for example, don't take
:kindly to starting a read and being interrupted in the middle to do a new
:read.

This issue is common to any concurrency model. But the answer is simple:
"If it isn't benign, don't allow concurrent reads".

:You may not think it's too hard, but I suspect you haven't encountered
:many of these real-life systems.

You could be right. Perhaps, I've learnt nothing from my 8 years realtime 
experience (including 3 years hard realtime). (I think combat systems qualify
for hard realtime - at least, I found it quite hard. :) 


:> :Just out of curiosity, can the "local" section make reference to these
:> :objects?
:> 
:> Can't recall (and couldn't see from a quick glance at OOSC-2) but do know
:> you would be limited in what you could do. For example, a local separate
:> object couldn't be the target of a call. Why do you ask?
:
:Because you said that they were locked between the "do" and "end". If they
:can be referenced in the local section, but are not locked, this would seem
:to be a Bad Thing.

It appears the reattachment rules would ensure that it can only reference a 
locked object.

:> :Correct me if I'm wrong, but no other thread can run while do_something is
:> :executing?
:> 
:> On a single processor, yes. 
:> On a multiple processor, no.

Sorry, this was misleading. Another thread can run if the original blocks.
 
:> :Or are you saying it can be interrupted, just that no other thread
:> :can access the objects referenced in the parameter list (or any objects
:> :referenced in _their_ parameter lists? )?
:> 
:> Correct.
:
:OK, this makes more sense. However, it does mean that my original comment
:is correct -- assertions at the object level cannot be added up to
:form the thread time, since threads can be interrupted. That's all
:I needed to know.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                               ` Don Harrison
@ 1997-08-19  0:00                                                 ` Lee Webber
  1997-08-20  0:00                                                 ` Ken Garlington
  1 sibling, 0 replies; 255+ messages in thread
From: Lee Webber @ 1997-08-19  0:00 UTC (permalink / raw)



On Tue, 19 Aug 1997 02:18:04 GMT, donh@syd.csa.com.au (Don Harrison)
wrote:

>Ken Garlington wrote:
>
>:Don Harrison wrote:

>That *is* how blocking works under SCOOP. The operation of the supplier object 
>contains the precondition, so the supplier determines the (synchronisation) 
>contract.

It's not clear to me that we're getting at the truth here on either
side.  Let me throw in an example and we can go from there.
(Caveat: I'm not a guru, but I have just finished studying chapter 30
of OOSC2 very closely.)

Assume:

   two objects X and Y on which we want to synchronize.
   a client C that wants exclusive access to them.

We will assume that when X and Y were instantiated, they were attached
to 'separate' entities x and y.  This is not necessary for
exclusivity, but most interesting cases happen this way as far as I
can see.

Now to get exclusive access to X and Y, C has to define a feature as
follows:

feature access_xy (separate xx, yy) is
require
   conditions_on_x	-- if these are not met, access_xy blocks
   conditions_on_y
do
     -- at this point, C has exclusive access to X and Y
    operations_on_x
    operations_on_y    -- possibly interleaved
end
     -- at this point, C has given up X and Y

Now my point.  It is likely that operations_on_x and operations_on_y
have preconditions.  However, it is not those preconditions that are
used for blocking, but the preconditions on access_xy.  Hopefully,
the latter subsume the former to the extent they do not ensure them
directly, but it's not enforced.  SCOOP requires you to duplicate the
preconditions if you want to block on them.

So DH's statement above is only true if C is considered the supplier!
Now normally that would be the case -- i.e., a wrapper class is
written that performs the synchronization functions and is then called
by the real client -- but it must be made clear that the class(es) to
be synchronized on do not directly specify the blocking preconditions.


See OOSC2 p. 996.

>
>:In order for the
>:threads that use this object to decide the outcome of their "duel", don't
>:they have to know the internal operation of the object -- an object contract
>:violation?
>
>No, only the object has to know (and how to restore its invariant - ie. how 
>to return to a consistent state).

On the other hand, DH is correct here. The exception occurs in the
object being contended for (the one that is executing a routine at the
time -- there can be at most one such).  (Question for guru'ier
people: what happens if the challenge occurs when access_to_xy is
calling a non-separate object?  Who gets the exception?)





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                                 ` Don Harrison
@ 1997-08-20  0:00                                                   ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-20  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> Ken Garlington wrote:
> 
> :Don Harrison wrote:
> 
> So, how does the runtime system select which queue to take the next call from?
> Is it arbitrary? ..or the one for the first declared entry? ..something else?

See http://www.adahome.com/rm95/rm9x-09-05-03.html para (17):

"If calls from two or more queues are simultaneously eligible for
selection,
the default entry queuing policy does not specify which queue is
serviced first.
Other entry queuing policies can be specified by pragmas (see D.4)."

> I think entries, by default, should be serviced in the order in which they
> are received by the object - which implies object-based, rather than entry-based
> queueing. This is how SCOOP works.

If you prefer this, you can use Priority_Queuing as described in D.4, or
just
provide a single entry to the object (with a parameter denoting what
needs to
be done). The extra flexibility of multiple queues lets you provide
different
entries for different priorities, so that you can take calls "out of
order"
based on some policy.

> 
> :.. any entry can be requeued. Furthermore, it's not up to the caller or callee,
> :it's up to the protected object:
> 
> The callee *is* the protected object. What do you mean by callee?

I meant to say "either caller" - the two tasks that would be dueling in
SCOOP.

> :"A requeue_statement can be used to complete an accept_statement or entry_body,
> :while redirecting the corresponding entry call to a new (or the same) entry
> :queue. Such a requeue can be performed with or without allowing an
> :intermediate cancellation of the call, due to an abort or the expiration
> :of a delay."
> :
> :"A requeue_statement shall be within a callable construct that is either an
> :entry_body or an accept_statement, and this construct shall be the innermost
> :enclosing body or callable construct."
> :
> :Again, the internal timing/sequence requirements can be hidden within the
> :object. It makes the decisions based on its internal state, ..
> 
> Seems okay.
> 
> :> :> IMO, "requeue" is a wokaround to a design flaw in Ada's concurrency - namely
> :> :> locking at the object level. Further, it's a *deficient* workaround because
> :> :> supplier objects are forced to do things (do_y) that should be the
> :> :> responsibility of clients (do_something).
> 
> I think I probably misunderstood requeue's purpose here. The criticism of
> object-level locking reamains valid, though.

If you say so...

> 
> :> I think it will be fine for *any* size system. Obviously, it will require a
> :> different design approach to that used with Ada because of some fundamental
> :> differences. These differences make it both more restrictive (in reliability-
> :> enhancing ways) and less restrictive (in ways that enhance reuse and modelling
> :> integrity).
> :
> :The design approaches I describe didn't come with Ada. They've been around
> :since assembly days. The same issues are described in real-time courses
> :regardless of implementation language.
> :
> :It would be interested to take some examples from these courses, such as the
> :HAS Buoy, Cruise Control, and ATD/CWM case studies from the ADARTS material,
> :and have them coded in SCOOP and executed.
> 
> I agree - it would. If I get a chance, I'll take a look. Where are they?

See http://www.software.org for more information.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                                   ` Ken Garlington
@ 1997-08-20  0:00                                                     ` Nick Leaton
  1997-08-20  0:00                                                       ` Nasser
  1997-08-21  0:00                                                       ` Jon S Anthony
  1997-08-21  0:00                                                     ` Joachim Durchholz
  1 sibling, 2 replies; 255+ messages in thread
From: Nick Leaton @ 1997-08-20  0:00 UTC (permalink / raw)



> To demonstrate the problem, attempt to encode the critical Ariane 5
> assumption as a "top-level abstract class." It is not directly
> representable
> as code, even as a "top-level" abstraction.

But neither are any of the specs you have for a fighter aircraft. Just
as you have to decompose your code, you have to decompose you assertions
or specifications. Just because you can't write
'fly plane' and be done with it in Eiffel (or Ada) it doesn't make DBC
wrong.

> Said another way, could you write "War and Peace" as a "top-level"
> abstraction?

Ok.

A hit B and made up.

-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                               ` Robert Dewar
@ 1997-08-20  0:00                                                 ` Nick Leaton
  1997-08-21  0:00                                                   ` Jon S Anthony
  1997-08-21  0:00                                                   ` Joachim Durchholz
  1997-08-20  0:00                                                 ` Lee Webber
  1 sibling, 2 replies; 255+ messages in thread
From: Nick Leaton @ 1997-08-20  0:00 UTC (permalink / raw)



Robert Dewar wrote:
> 
> Bertrand says
> 
> <<You obviously must know better. The postcondition, if it
> needs to be expressed, is something like "string XXX" [the
> argument to the routine] "has been appended to the output".
> With the proper model this is easy to express formally.>>
> 
> But that's the whole point. Sure you can write a (pretty useless)
> postcondition after
> 
> print ("this is my useless error message");
> 
> to make sure you have added that string to the output file, but that tests
> only whether your code is working, not whether it meets the specification,
> which was to produce intelligible error messages. And I do not know what
> you mean by "know better". If you mean do I know perfectly well that
> postconditions cannot capture this kind of specification, yes, I know
> that perfectly well -- many specifications and requirements cannot be
> formalized in any useful manner.

But who should be resposible for the error message? You have a choice
between client of print and print itself.

The answer must be the client, because as the client, I may want to
handle errors in different ways. Pop up a window, or print to a console
window as two reasonable examples.

So having a postcondition that checks to see that the string has been
added to the output condition is fine, tells me something about what the
routine does, and acts as a check that it does the work.

Producing an error message is not print's problem. Lets say there are
preconditions of 1) the file being open for writing, and 2) the string
not being void (C++ null). Either being false when you call print is an
error, and will raise an exception, which can be caught, or you can
check before you call the routine if you cannot tell at compile time,
for example because the string came from some user input.

So as a result you have to have checks in the client. 

However if I write print ("Cest un crado error") you may complain that
it is an intelligible error message. OK, it may be for you. But if you
cannot express specifications and requirements in code, how can you
write a system? 

Take the example of useability. What 'exactly' does it mean? How do you
measure it? At the end of the day you have to write something which is
decomposing 'useablility' into code. I don't see why you can do the same
with DBC. Although, you may omit some of the checks for pragmatic
reasons.

For another example. I write software for a bank. A requirement is that
we help prevent the bank going bust. A very valid requirement. However,
this is a very woolly spec, and needs to be decomposed into smaller,
manageable requirements.


-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                               ` Robert Dewar
  1997-08-20  0:00                                                 ` Nick Leaton
@ 1997-08-20  0:00                                                 ` Lee Webber
  1997-08-21  0:00                                                   ` Don Harrison
  1 sibling, 1 reply; 255+ messages in thread
From: Lee Webber @ 1997-08-20  0:00 UTC (permalink / raw)



On 19 Aug 1997 22:33:04 -0400, dewar@merv.cs.nyu.edu (Robert Dewar)
wrote:

>Bertrand says
>
><<You obviously must know better. The postcondition, if it
>needs to be expressed, is something like "string XXX" [the
>argument to the routine] "has been appended to the output".
>With the proper model this is easy to express formally.>>
>
>But that's the whole point. Sure you can write a (pretty useless)
>postcondition after 
>
>print ("this is my useless error message");
>
>to make sure you have added that string to the output file, but that tests
>only whether your code is working, not whether it meets the specification,
>which was to produce intelligible error messages. And I do not know what
>you mean by "know better". If you mean do I know perfectly well that
>postconditions cannot capture this kind of specification, yes, I know
>that perfectly well -- many specifications and requirements cannot be
>formalized in any useful manner.
>

You've got a point here, but I think you're making too much of it.
This is a problem with all specification, not just assertions: you
can't formally specify an interface between a component of your system
and an external entity that itself is not specifiable.  But of course
everyone knows that.

This problem propagates all the way back to the requirements (how do
you engineer an "intelligible" set of messages so that they are
guaranteed to pass an acceptance test unless you specify the
acceptance test in advance?).  It isn't really an issue for the
solution domain.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-20  0:00                                                     ` Nick Leaton
@ 1997-08-20  0:00                                                       ` Nasser
  1997-08-21  0:00                                                       ` Jon S Anthony
  1 sibling, 0 replies; 255+ messages in thread
From: Nasser @ 1997-08-20  0:00 UTC (permalink / raw)



In article <33FAB35A.18AA15BB@calfp.co.uk>, Nick says...
>
>> Said another way, could you write "War and Peace" as a "top-level"
>> abstraction?
>
>Ok.
>
>A hit B and made up.
>

I dont think This is abstract enough. too much detailes exposed 
to the client. How about representing "war" and "peace" as object instances of
abstract class "Mixed feelings" , and the "making up" part  is a method 
implemented as a generic instantiation of some "human act <>" function?

I think you'll agree this is more abstract than "A hit B and make up" .

Nasser




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-18  0:00                                                 ` Matt Austern
@ 1997-08-20  0:00                                                   ` Joachim Durchholz
  1997-08-21  0:00                                                     ` Jon S Anthony
  0 siblings, 1 reply; 255+ messages in thread
From: Joachim Durchholz @ 1997-08-20  0:00 UTC (permalink / raw)



Matt Austern wrote:
> For example, what's the postcondition for a function that sorts a
> range?  Three postconditions, of course: the range is sorted, the
> range has the same number of elements as it did before, and the new
> range is a permutation of the old range. (Depending on the sorting
> algorithm, you might also have a postcondition that guarantees
> stability of equivalent elements.) It's the last one that's a problem;
> I never did figure out how to write a postcondition like that in
> Eiffel, and I as far as I know it isn't possible.

I wouldn't write any of these postconditions in Eiffel; I'd include them
in comments. The environment won't check these postconditions for me,
true - but I retain the documentation of the routine, at a place where
it is easily accessible.

> In every language, it's certainly important to document carefully what
> a function requires and what it guarantees to do.  Eiffel is similar
> to all other languages in that many of these requirements and
> guarantees have to live in the documentation rather than in the code.

Document non-executable stuff in comments. Have your documentation
generated automatically. No redundancy, documentation is easy to do
along with the formal specs (class interfaces) and/or the coding
(routines).

Regards,
Joachim
-- 
Please don't send unsolicited ads.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                               ` Don Harrison
  1997-08-19  0:00                                                 ` Lee Webber
@ 1997-08-20  0:00                                                 ` Ken Garlington
  1997-08-21  0:00                                                   ` Don Harrison
  1 sibling, 1 reply; 255+ messages in thread
From: Ken Garlington @ 1997-08-20  0:00 UTC (permalink / raw)



Don Harrison wrote:
> 
> I think it depends what you use priorities for. If you use them for their
> intended purpose of ensuring threads meet their deadlines, then they only
> need be applied to threads that have deadlines.

In feedback systems, it is a fundamental property that most of the
threads
have explicit deadlines, or the analog transfer function you've
discretized
will not be appropriately implemented.

> The problem is many Ada developers misuse priorities to acheive correct
> synchronisation. Realtime systems that misuse priorities in this way tend
> (not surprisingly) to be very fragile, suffering from race conditions.
> The basic problem with using priorities for syncronisation is that you cannot
> guarantee correct behaviour. It is the *wrong* tool for the job. So, what's
> the right tool?

Possibly true, although I've never seen it done (for the obvious reason
you cite!)

> It's Design by Contract! Why? Because it allows you to express the necessary
> (*blocking*) conditions which are assumed to exist when a concurrent operation
> is executed.

So can Ada.

> We recall that when those assumptions are violated in a sequential
> context, an exception is raised. In a concurrent context (ie. when the
> precondition involves a separate object), they assume synchronisation semantics.
> The caller blocks till another thread performs does something which causes the
> precondition to now be satisfied.
> 
> For example, an operation adding an item to a buffer:
> 
>   add_to_buffer (b: BUFFER; item: SOME_TYPE) is
>   require not b.full
>   do
>     b.add (item)
>   end
> 
> Because b is non-separate (sequential), the precondition will fail if b is full.
> 
>   add_to_buffer (b: separate BUFFER; item: SOME_TYPE) is
>   require not b.full
>   do
>     b.add (item)
>   end
> 
> Because b is separate (concurrent), the precondition will cause blocking until
> another thread removes an item from the buffer (ie. b is not full).
> 
> Any Ada developer reading this should immediately recognise the similarity
> with guarded task entries and barriers on protected type entries. These
> mechanisms, then, are additional ways (apart from predefined assertions (think
> program_error etc.) and range-constrained subtypes) in which Ada provides some
> support for DBC. In fact, because guards and barriers are *general* boolean
> expressions, they are about as close as Ada gets to the generality of Eiifel's
> support for DBC.
> 
> Now, back to the priority issue..
> 
> Because, under SCOOP, you can apply such synchronisation assertions to any
> separate object, you are able to specify precisely the assumptions relevant
> to the operations offered by those objects and guarantee correct use.
> This leaves priorities to be used for what their proper use - expressing
> relative importance of threads for facilitating timeliness. Consequently,
> I expect a system implemented using SCOOP would have more "priority-less"
> threads.

Unfortunately, systems that represent digital models of analog functions
(e.g.
flight controls, IRSs) will confound your expectations :)

> 
> 
> :> Where timing *is* an issue, you use express messages. This mechanism allows
> :> threads to dynamically change their "priority" relative to other threads.
> :> This mechanism should only be used where it's critical to transfer control.
> :> There are two parties involved - the holder and the challenger - and they "duel"
> :> for control of a resource. Duels either result in a transfer of control or
> :> the challenger waiting till the holder finishes with the resource.
> :
> :Does this mean that each thread has to know it's relative priority to all other
> :threads (more to the point, thread interfaces)?
> 
> No, but it does suggest the priority of a thread relative to all threads that
> it interacts with must be known.

That, to me, seems to be a problem with respect to encapsulating this
information
(which is what I want to do).

>  I'm not aware of any published information
> about how this is intended to work but imagine it could use abslolute priorities
> (so implying relative ones):
> 
>   set_priority (p: PRIORITY) is ..        -- set absolute priority
>   yield (p: PRIORITY) is ..               -- yield to priority p or greater
>   etc.
> 
> :That would be a serious maintainability issue, I would think.
> 
> Yes, if it were true - but it isn't.

See above. If the relative priority of each interaction is distributed,
then
it's true.

> 
> :>   - A thread which absolutely must execute (possibly driven by a timer) can
> :>     issue a challenge for a resource.
> :
> :If, while another thread is operating, it cannot be interrrupted (as your
> :previous note said, a thread cannot be interrupted even between object calls),
> :then how does the other thread begin execution to issue the challenge?
> 
> We're talking single processor here, of course (the issue doesn't arise with
> multi-processors). An executing thread will give up the processor to another
> thread if it blocks on a synchronisation condition (a precondition on a
> separate object). 

Not in the real word of embedded systems. Think about non-maskable
hardware
interrupts.

> Expanding the buffer example above:
> 
>   x: separate BUFFER
>   s: SOME_TYPE
>   ...
> 
>   do_something is
>   do
>     ...
>     add_to_buffer (x, s)
>     ...
>   end
> 
> do_something may block on the call to add_to_buffer (because the buffer is full)
> causing another thread to run.
> 
> :> I was also concerned about this issue initially but came to the conclusion
> :> that objects would be locked for just as long as they (safely) need to be.
> :> Where it's important to release a frequently used shared resource quickly,
> :> various design strategies can be applied to minimise locking.
> :
> :Don't these "design strategies" cause the same uncertainly that you said
> :you didn't want?
> 
> No.

Why not? Can't the developer (whom you don't trust) fail to properly
implement
these "design strategies"?

> Also, these techniques can be applied to *any* concurrent system - they
> are not SCOOP-specific. Hence, they're not relevant to any discussion about
> the relative merits of different concurrency models.

Are there deployed systems that use these techniques?

> 
> :For example, if a lower-priority thread agrees to give up control
> :of an object to a higher-priority thread, then race conditions are possible
> :if the threads are not designed properly.
> 
> Assertions would help you to design them properly and avoid such conditions.

See above. Your original position was that the compiler should take care
of
all of this, so that the designer would not make an error. Now you
depend
upon the designer to implement the timing process properly (and write
the
proper assertions; an issue which my Ariane response addresses in some
detail).

> Also, invariants will guarantee that an object yielding in a duel will end
> up in a consistent state.
> 
> :This seems counter-intuitive. Consider the simple protected object discussed
> :earlier with the Read and Write operations. It would seem that the object
> :itself, with its internal knowledge of how Read and Write works, would be
> :the better place to control when blocking needs to occur.
> 
> That *is* how blocking works under SCOOP. The operation of the supplier object
> contains the precondition, so the supplier determines the (synchronisation)
> contract.
> 
> :In order for the
> :threads that use this object to decide the outcome of their "duel", don't
> :they have to know the internal operation of the object -- an object contract
> :violation?
> 
> No, only the object has to know (and how to restore its invariant - ie. how
> to return to a consistent state).

You're using the word "no" a lot without explanation. Two callers to the
object decide between *themselves* who gets to maintain access. Now it's
the
called object that determines the outcome of the duel?

You've pretty much worked me around in circles. I think I'll just wait
until
someone actually uses SCOOP to make up my mind.


> 
> :> :Priority inversion would also seem to be much more likely.
> :>
> :> Can you explain what you mean by this?
> :
> :Priority inversion? When a low prioity task seizes a high prioity resource,
> :it effectively operates at the priority of the seized resource. If a high
> :priority task then attempts to seize the resource, it is effectively blocked
> :by the lower priority task -- priority inversion. However, since you can in
> :fact have a thread interrupt another thread (has to happen, otherwise there
> :is no "dueling"), and since the higher-priority thread can seize the lower
> :one, I assume this can be avoided.
> 
> Correct.
> 
> :However, it also opens the door to both mutual exclusion and deadlock.
> 
> ..which are avoided (as in *any* concurrent system) by designing correctly.
> 
> :> No. In this case, the reads could occur concurrently (due to optimisations).
> :
> :Describe the general-purpose algorithm used to determince this by a compiler.
> 
> Ask Robert Dewar because that's what happens with protected types.  :)

ABSOLUTELY NOT. The developer of the protected type explicitly provides
the
criteria; there's no magic going on in the compiler. I think your
understanding
of Ada is at least as hazy as my understanding of SCOOP :)

> 
> :> :You claimed that the compiler could optimize the timing properties of
> :> :the system; I would be interested in seeing such a compiler..
> :>
> :> I don't think it would be too hard. The compiler just has to verify that
> :> queries (functions) are truly benign
> :
> :Define "benign"! For example, is a read of a memory location "benign"?
> :Maybe not, if it's memory-mapped I/O. Some devices, for example, don't take
> :kindly to starting a read and being interrupted in the middle to do a new
> :read.
> 
> This issue is common to any concurrency model.

Which is why it's a situation that the _developer_, not the compiler,
must address. It is also why the language has to give the _developer_
the flexibility to address it (even if he is still capable of shooting
himself in the foot).

> But the answer is simple:
> "If it isn't benign, don't allow concurrent reads".

To repeat: Define "benign!!!!!!!!" It has to be sufficiently loose to
permit
working systems, but tight enough to prohibit concurrency faults (your
original claim).

> 
> :You may not think it's too hard, but I suspect you haven't encountered
> :many of these real-life systems.
> 
> You could be right. Perhaps, I've learnt nothing from my 8 years realtime
> experience (including 3 years hard realtime). (I think combat systems qualify
> for hard realtime - at least, I found it quite hard. :)

Absolutely not, if the combat systems (1) were not _embedded_ (which is
where
many of these problems come up), (2) had minimal OS support (I've seen
workstation
programmers with over ten years experience with realtime systems that
have
never had to worry about these issues), and (3) had to deal with hard
realtime
in the sense that the system _totally fails_ if a complex set of
deadlines
fail -- as opposed to the user getting irritated that the system is too
slow.

> 
> :> :Just out of curiosity, can the "local" section make reference to these
> :> :objects?
> :>
> :> Can't recall (and couldn't see from a quick glance at OOSC-2) but do know
> :> you would be limited in what you could do. For example, a local separate
> :> object couldn't be the target of a call. Why do you ask?
> :
> :Because you said that they were locked between the "do" and "end". If they
> :can be referenced in the local section, but are not locked, this would seem
> :to be a Bad Thing.
> 
> It appears the reattachment rules would ensure that it can only reference a
> locked object.
> 
> :> :Correct me if I'm wrong, but no other thread can run while do_something is
> :> :executing?
> :>
> :> On a single processor, yes.
> :> On a multiple processor, no.
> 
> Sorry, this was misleading. Another thread can run if the original blocks.
> 
> :> :Or are you saying it can be interrupted, just that no other thread
> :> :can access the objects referenced in the parameter list (or any objects
> :> :referenced in _their_ parameter lists? )?
> :>
> :> Correct.
> :
> :OK, this makes more sense. However, it does mean that my original comment
> :is correct -- assertions at the object level cannot be added up to
> :form the thread time, since threads can be interrupted. That's all
> :I needed to know.
> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                           ` Robert Dewar
  1997-08-19  0:00                                             ` Bertrand Meyer
  1997-08-19  0:00                                             ` Nick Leaton
@ 1997-08-20  0:00                                             ` Ken Garlington
  1997-08-26  0:00                                             ` Richard A. O'Keefe
  3 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-20  0:00 UTC (permalink / raw)



Robert Dewar wrote:
> 
> pragma Assert (programmer now understands what they did wrong);
> 
> You need a *really* clever language to test that one (well I suppose the
> assertion routine executed at runtime could ask the programmer whether
> he understood :-)

No, you just need to code this in a top-level abstraction :)




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-20  0:00                                                 ` Nick Leaton
  1997-08-21  0:00                                                   ` Jon S Anthony
@ 1997-08-21  0:00                                                   ` Joachim Durchholz
  1 sibling, 0 replies; 255+ messages in thread
From: Joachim Durchholz @ 1997-08-21  0:00 UTC (permalink / raw)



Nick Leaton wrote:
> However if I write print ("Cest un crado error") you may complain that
> it is an intelligible error message. OK, it may be for you. But if you
> cannot express specifications and requirements in code, how can you
> write a system?
> 
> Take the example of useability. What 'exactly' does it mean? How do
> you
> measure it? At the end of the day you have to write something which is
> decomposing 'useablility' into code. I don't see why you can do the
> same
> with DBC. Although, you may omit some of the checks for pragmatic
> reasons.

That's exactly what's being done - such assertions are written as
comments (which doesn't mean they don't bind the caller or the routine).
Though stuff like usability is difficult to express even as a comment
that's better than "this routine is user-friendly" - no wonder usability
labs are in existence.

> For another example. I write software for a bank. A requirement is
> that
> we help prevent the bank going bust. A very valid requirement.
> However,
> this is a very woolly spec, and needs to be decomposed into smaller,
> manageable requirements.

Same case as above.

Such assertions go to the currently perceived top-level function of the
system. In practice, the top-level function isn't too important (it will
change as soon as we go from batch to interactive, add another service
to the system, etc. etc. ...) If the top-level function is unimportant,
so are its assertions :)

Regards,
Joachim
-- 
Please don't send unsolicited ads.





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-20  0:00                                                 ` Ken Garlington
@ 1997-08-21  0:00                                                   ` Don Harrison
  0 siblings, 0 replies; 255+ messages in thread
From: Don Harrison @ 1997-08-21  0:00 UTC (permalink / raw)



Ken Garlington wrote:

:Don Harrison wrote:

[...]

:> The problem is many Ada developers misuse priorities to acheive correct
:> synchronisation. Realtime systems that misuse priorities in this way tend
:> (not surprisingly) to be very fragile, suffering from race conditions.
:> The basic problem with using priorities for syncronisation is that you cannot
:> guarantee correct behaviour. It is the *wrong* tool for the job. So, what's
:> the right tool?
:
:Possibly true, although I've never seen it done (for the obvious reason
:you cite!)

I find that hard to believe. Judging by the sort of problems that have been 
raised in this thread alone, that's *exactly* how a lot of Ada software works.

[...]

:> Now, back to the priority issue..
:> 
:> Because, under SCOOP, you can apply such synchronisation assertions to any
:> separate object, you are able to specify precisely the assumptions relevant
:> to the operations offered by those objects and guarantee correct use.
:> This leaves priorities to be used for what their proper use - expressing
:> relative importance of threads for facilitating timeliness. Consequently,
:> I expect a system implemented using SCOOP would have more "priority-less"
:> threads.
:
:Unfortunately, systems that represent digital models of analog functions (e.g.
:flight controls, IRSs) will confound your expectations :)

..in spite of not having any expectations of them. If you say so.

What I *do* expect is that more prioritisation is required the more numerous 
and more stringent timing constraints become. 


[...]

:>  I'm not aware of any published information
:> about how this is intended to work but imagine it could use abslolute priorities
:> (so implying relative ones):
:> 
:>   set_priority (p: PRIORITY) is ..        -- set absolute priority
:>   yield (p: PRIORITY) is ..               -- yield to priority p or greater
:>   etc.
:> 
:> :That would be a serious maintainability issue, I would think.
:> 
:> Yes, if it were true - but it isn't.
:
:See above. If the relative priority of each interaction is distributed, then
:it's true.

Perhaps you haven't grasped what I'm saying here. I'm saying that's exactly 
what you *wouldn't* do. You would use absolute priorities (as you do in Ada)
to *imply* relative ones.


:> :>   - A thread which absolutely must execute (possibly driven by a timer) can
:> :>     issue a challenge for a resource.
:> :
:> :If, while another thread is operating, it cannot be interrrupted (as your
:> :previous note said, a thread cannot be interrupted even between object calls),
:> :then how does the other thread begin execution to issue the challenge?
:> 
:> We're talking single processor here, of course (the issue doesn't arise with
:> multi-processors). An executing thread will give up the processor to another
:> thread if it blocks on a synchronisation condition (a precondition on a
:> separate object). 
:
:Not in the real word of embedded systems. Think about non-maskable hardware
:interrupts.

Not sure what you mean by "non-maskable .. interrupts". Care to explain?
However, wrt interrupts generally, a SCOOP implementation could provide 
an external mechanism for attaching routines to interrupts. This information 
would appear in an external configuration file as for non-benign functions (see 
below).


:> :> I was also concerned about this issue initially but came to the conclusion
:> :> that objects would be locked for just as long as they (safely) need to be.
:> :> Where it's important to release a frequently used shared resource quickly,
:> :> various design strategies can be applied to minimise locking.
:> :
:> :Don't these "design strategies" cause the same uncertainly that you said
:> :you didn't want?
:> 
:> No.
:
:Why not? Can't the developer (whom you don't trust) fail to properly implement
:these "design strategies"?

Here it is again (since you obviously missed it the first time)..

:> Also, these techniques can be applied to *any* concurrent system - they
:> are not SCOOP-specific. Hence, they're not relevant to any discussion about
:> the relative merits of different concurrency models.
:
:Are there deployed systems that use these techniques?

Yes, you probably use them yourself. :)

:> :For example, if a lower-priority thread agrees to give up control
:> :of an object to a higher-priority thread, then race conditions are possible
:> :if the threads are not designed properly.
:> 
:> Assertions would help you to design them properly and avoid such conditions.
:
:... Your original position was that the compiler should take care of
:all of this, so that the designer would not make an error. 

Rubbish! Report accurately what I say or forget about discussing anything.

What I *did* say was something like "Under SCOOP, race conditions would not
be an issue..". "Under SCOOP" implies not just using the mechanism but using
it to its full potential. If you use (synchronisation) assertions to document 
your assumptions, race conditions shouldn't exist. Naturally, race conditions
*will* exist in the absence of such specifications.

Having said that, I need to clarify what I mean by "race conditions". I mean 
incorrect behaviour resulting from inadequate (or non-existent) synchronisation.
I *don't* mean thread starvation or deadlock. These are avoided by designing 
correctly.

:Now you depend upon the designer to implement the timing process properly 
(and write the proper assertions; 

No, that was always implied. You incorrectly *assumed* I meant something else.


:> Also, invariants will guarantee that an object yielding in a duel will end
:> up in a consistent state.
:> 
:> :This seems counter-intuitive. Consider the simple protected object discussed
:> :earlier with the Read and Write operations. It would seem that the object
:> :itself, with its internal knowledge of how Read and Write works, would be
:> :the better place to control when blocking needs to occur.
:> 
:> That *is* how blocking works under SCOOP. The operation of the supplier object
:> contains the precondition, so the supplier determines the (synchronisation)
:> contract.
:> 
:> :In order for the
:> :threads that use this object to decide the outcome of their "duel", don't
:> :they have to know the internal operation of the object -- an object contract
:> :violation?

Sorry, I should have pointed out here you're confusing blocking and duels.

In the case of blocking, the callee determines how a caller will synchronise 
with it. In the case of callers duelling for a callee, their relative 
"priorities" (probably inferred from absolute priorities) will determine the 
outcome of the duel.

:> No, only the object has to know (and how to restore its invariant - ie. how
:> to return to a consistent state).

Sorry, I gave you a bum steer here. :(

The state of a called object has nothing to do with the outcome of a duel - 
it's determined by the relative "priorities" of the callers (duellers). My 
explanations of blocking and duels may make more sense to you now if you re-read 
them.

:You've pretty much worked me around in circles. 

Thank you. :)


:> :Describe the general-purpose algorithm used to determince this by a compiler.
:> 
:> Ask Robert Dewar because that's what happens with protected types.  :)
:
:ABSOLUTELY NOT. The developer of the protected type explicitly provides the
:criteria; there's no magic going on in the compiler. I think your understanding
:of Ada is at least as hazy as my understanding of SCOOP :)

We may be talking about different things here. I'm talking about the ability
to have concurrent reads (queries). This is precisely what happens with 
protected types (where functions can be executed concurrently) so the 
optimisations I say are possible in SCOOP would be materially no different from
those implemented for protected types.


:> :> :You claimed that the compiler could optimize the timing properties of
:> :> :the system; I would be interested in seeing such a compiler..
:> :>
:> :> I don't think it would be too hard. The compiler just has to verify that
:> :> queries (functions) are truly benign
:> :
:> :Define "benign"! For example, is a read of a memory location "benign"?
:> :Maybe not, if it's memory-mapped I/O. Some devices, for example, don't take
:> :kindly to starting a read and being interrupted in the middle to do a new
:> :read.

A function is "benign" if it has no side-effects. That is calling it (and,
possibly, interrupting it in the middle) will not change the state of the 
system - software *and* hardware.

:> This issue is common to any concurrency model.
:
:Which is why it's a situation that the _developer_, not the compiler,
:must address. It is also why the language has to give the _developer_
:the flexibility to address it (even if he is still capable of shooting
:himself in the foot).

Sure. A SCOOP implementation could provide for this in an external configuration
file, for example. This would be a better option, IMO, than some language 
construct. An appropriate mechanism will give you both efficient sharing of 
resources and safety.


:> :You may not think it's too hard, but I suspect you haven't encountered
:> :many of these real-life systems.
:> 
:> You could be right. Perhaps, I've learnt nothing from my 8 years realtime
:> experience (including 3 years hard realtime). (I think combat systems qualify
:> for hard realtime - at least, I found it quite hard. :)
:
:Absolutely not, if the combat systems (1) were not _embedded_ (which is where
:many of these problems come up), (2) had minimal OS support (I've seen workstation
:programmers with over ten years experience with realtime systems that have
:never had to worry about these issues), and (3) had to deal with hard realtime
:in the sense that the system _totally fails_ if a complex set of deadlines
:fail -- as opposed to the user getting irritated that the system is too slow.

My combat systems qualifies on all counts but, frankly, its quite irrelevant
to whether what I have to say has any substance.

IMHO, sprouting one's experience (or academic credentials) as though it is the 
final arbiter of truth is just pissing on power poles. Rather than adding weight 
to one's arguments, it betrays the fact you think you know it all. Sadly, anyone 
with that sort of attitude is impervious to learning anything new.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-20  0:00                                                 ` Lee Webber
@ 1997-08-21  0:00                                                   ` Don Harrison
  1997-08-23  0:00                                                     ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Don Harrison @ 1997-08-21  0:00 UTC (permalink / raw)



Lee Webber wrote:

:Robert Dewar wrote:
:
:>... many specifications and requirements cannot be
:>formalized in any useful manner.
:
:You've got a point here, but I think you're making too much of it.
:This is a problem with all specification, not just assertions: 

Exactly, and typically such requirements are both untestable yet obviously 
desirable (intelligible messages, for example). As a basic rule, if you can't 
specify something in verifiable terms, then it shouldn't be specified as a 
requirement. It should be recorded as desirable behaviour ("will" rather than 
"shall"): 

  "Messages to the operator will be intelligible".

Having said that, it's also true that verifiable specifications *do* get omitted
from specifications, not because it's impossible to specify them, but because 
they're difficult to specify. Although some are unlikely to admit it, the Ariane 
profile thingo probably falls into that category.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                                   ` Ken Garlington
  1997-08-20  0:00                                                     ` Nick Leaton
@ 1997-08-21  0:00                                                     ` Joachim Durchholz
  1997-08-23  0:00                                                       ` Ken Garlington
  1 sibling, 1 reply; 255+ messages in thread
From: Joachim Durchholz @ 1997-08-21  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> > The issue is that DBC allows to integrate code and code
> documentation
> > better. It is possible to write top-level abstract classes that just
> > encapsulate a few assertions; there is no need to duplicate these
> > assertions in other documents, at Eiffel (at this level) is easy to
> read
> > even for a non-programmer.
> 
> To demonstrate the problem, attempt to encode the critical Ariane 5
> assumption as a "top-level abstract class." It is not directly
> representable
> as code, even as a "top-level" abstraction.
> 
> Said another way, could you write "War and Peace" as a "top-level"
> abstraction?

People keep mixing the documentation aspects and the run-time checking
aspects of Eiffel assertions.

Assertions as documentation *need not be executable* (so there is no
problem encoding the critical Ariane-5 conditions or even War and Peace
as a precondition).
Assertions for run-time checking must be executable, of course. But even
these double up as documentation on the routine.

At its first stage, Design by Contract is just a discipline: write down
the preconditions and postconditions of the routine. Make sure the
preconditions and postconditions match what the routine does (easy, the
assertions are in the vicinity anyway). Have them stand out clearly via
keywords so that the "short" tool can create a documentation that
contains the routine signature with their pre- and postconditions.

The next level is that some assertions may be executable. This allows
run-time checking, and (more important) it encourages the programmer to
actually make assertions and code consistent. Even the non-executable
ones - anybody with some practice in getting the checkable assertions
right will have no trouble putting down precise non-executable
assertions.

> > > Again: You need to have experience in systems analysis and
> > > requirements
> > > capture to understand that the hard stuff is not readily
> > > expressible in code.
> >
> > Eiffel assertions are *not* code. They are specifications for code.
> >  Some of these specifications happen to be checkable at run-time,
> 
> Read both of these statements carefully, several times.
> That, coupled with the experiment I describe above, should demonstrate
> the problem with your thinking.

They don't. Either you don't understand me, or I don't understand you.
(BTW which two statements do you mean?)

Regards,
Joachim
-- 
Please don't send unsolicited ads.






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                               ` Ken Garlington
@ 1997-08-21  0:00                                                 ` Joachim Durchholz
  1997-08-23  0:00                                                   ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Joachim Durchholz @ 1997-08-21  0:00 UTC (permalink / raw)



Ken Garlington wrote:
> > There is a tool called "flat" that ... collects all assertions
> > from all ancestors and lists them with the final
> > routine. (There is even an option that gives just the signatures and
> > assertions, leaving out the routine bodies.)
> > This gives us full documentation about every routine of every class,
> > without having to refer to ancestor classes. So even if assertions
> are
> > comments, these comments get included in the flat form of any
> descendant
> > class.
> 
> Can't such an extra-language tool be equally valid with comments in
> any
> language (that has classes)?

Yes, and I'd advocate some tool of this type for every language.
Something similar is done for the Java AWT, where each routine is
documented via some comments with standardized keywords (the "keywords"
being single letters, making the comment rather unreadable...); the HTML
documentation for the AWT is obviously generated with a tool.
Unfortunately, inheritance isn't considered by that tool.

The advantage of this being part of the language definition is that
a) the conventions are the same for every shop (a mere comment
convention might be different, creating incompatibilities not with the
executable code but with the development environments)
b) Eiffel can make use of executable assertions and compile them as
run-time checks.

> > Actually it's not restricted style. It is just that comments that
> are in
> > certain parts of the class text (namely, the assertion sections)
> > automatically gets included in the flat form of descendants.
> 
> This doesn't sound like Eiffel assertions, which are compiled.

Eiffel assertions are not compiled if they take the form of a comment.
You can write something like

  feature sqrt (x: real): real is
  require
    nonnegative_argument: x >= 0
  do
    ... (lots of code omitted)
  ensure
    nonnegative_result: Result >= 0
    maximum_precision: -- Every mantissa bit except the last is correct
  end

The short tool will report this routine as

  feature sqrt (x: real): real is
  require
    nonnegative_argument: x >= 0
  ensure
    nonnegative_result: Result >= 0
    maximum_precision: -- Every mantissa bit except the last is correct
  end

so executable and non-executable assertions aren't handled any
differently for documentation purposes.

Regards,
Joachim
-- 
Please don't send unsolicited ads.






^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-20  0:00                                                   ` Joachim Durchholz
@ 1997-08-21  0:00                                                     ` Jon S Anthony
  1997-08-22  0:00                                                       ` Joachim Durchholz
  0 siblings, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-08-21  0:00 UTC (permalink / raw)



In article <33FA3B0F.62780A5C@munich.netsurf.de> Joachim Durchholz <joachim.durchholz@munich.netsurf.de> writes:

> Matt Austern wrote:
> > For example, what's the postcondition for a function that sorts a
> > range?  Three postconditions, of course: the range is sorted, the
> > range has the same number of elements as it did before, and the new
> > range is a permutation of the old range. (Depending on the sorting
> > algorithm, you might also have a postcondition that guarantees
> > stability of equivalent elements.) It's the last one that's a problem;
> > I never did figure out how to write a postcondition like that in
> > Eiffel, and I as far as I know it isn't possible.
> 
> I wouldn't write any of these postconditions in Eiffel; I'd include them
> in comments. The environment won't check these postconditions for me,
> true - but I retain the documentation of the routine, at a place where
> it is easily accessible.

So, how why write them in such a limited language (either Eiffel or
its assertion sublanguage).  What's the point?  Seems like if this is
your stance but you still want some formalism, you should write the
things in FOL.


> > In every language, it's certainly important to document carefully what
> > a function requires and what it guarantees to do.  Eiffel is similar
> > to all other languages in that many of these requirements and
> > guarantees have to live in the documentation rather than in the code.
> 
> Document non-executable stuff in comments. Have your documentation
> generated automatically. No redundancy, documentation is easy to do
> along with the formal specs (class interfaces) and/or the coding
> (routines).

Sounds OK (note that the non-executable stuff is typically the most
important in this sort of context).  Of course this is easily done in
any language...

/Jon

-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-20  0:00                                                 ` Nick Leaton
@ 1997-08-21  0:00                                                   ` Jon S Anthony
  1997-08-22  0:00                                                     ` Nick Leaton
  1997-08-21  0:00                                                   ` Joachim Durchholz
  1 sibling, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-08-21  0:00 UTC (permalink / raw)



In article <33FAB260.7E0CD1D1@calfp.co.uk> Nick Leaton <nickle@calfp.co.uk> writes:

> Robert Dewar wrote:
> > [...some BM stuff...]
> > you mean by "know better". If you mean do I know perfectly well that
> > postconditions cannot capture this kind of specification, yes, I know
> > that perfectly well -- many specifications and requirements cannot be
> > formalized in any useful manner.

What's really odd here is that BM does not give the impression that he
understands this point.  Go figure.


> But who should be resposible for the error message? You have a choice
> between client of print and print itself.

Hint: it is not the dichotomy as you suggest.


> The answer must be the client, because as the client, I may want to
> handle errors in different ways. Pop up a window, or print to a console
> window as two reasonable examples.

That's not the point.  The point is, what is expressed via the
_mechanisms_ you suggest.  This latter depends largely on the context
of who/what is using the system (client and print together).

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-20  0:00                                                     ` Nick Leaton
  1997-08-20  0:00                                                       ` Nasser
@ 1997-08-21  0:00                                                       ` Jon S Anthony
  1997-08-22  0:00                                                         ` Nick Leaton
  1 sibling, 1 reply; 255+ messages in thread
From: Jon S Anthony @ 1997-08-21  0:00 UTC (permalink / raw)



In article <33FAB35A.18AA15BB@calfp.co.uk> Nick Leaton <nickle@calfp.co.uk> writes:

> > To demonstrate the problem, attempt to encode the critical Ariane 5
> > assumption as a "top-level abstract class." It is not directly
> > representable
> > as code, even as a "top-level" abstraction.
> 
> But neither are any of the specs you have for a fighter

That's OK, Ken is not the one claiming that this can be done.  Meyer
and the E-Jihad are the ones making this fatuous claim.


> aircraft. Just as you have to decompose your code, you have to
> decompose you assertions or specifications. Just because you can't
> write 'fly plane' and be done with it in Eiffel (or Ada) it doesn't
> make DBC wrong.

Spoken like a true reductionist.  This is not a decomposition problem.
I tried to point this out before when I spoke about how this problem
is the direct analogue of the problem of "natural kinds" in knowlege
representation.  You can't come up with contextually independent
necessary and sufficient conditions for a definition for these things.
But that is basically what you are trying to claim _is_ possible.


> > Said another way, could you write "War and Peace" as a "top-level"
> > abstraction?
> 
> Ok.
> 
> A hit B and made up.

Not even close, :-)

/Jon
-- 
Jon Anthony
OMI, Belmont, MA 02178, 617.484.3383 
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-21  0:00                                                   ` Jon S Anthony
@ 1997-08-22  0:00                                                     ` Nick Leaton
  0 siblings, 0 replies; 255+ messages in thread
From: Nick Leaton @ 1997-08-22  0:00 UTC (permalink / raw)



Jon S Anthony wrote:

> > Robert Dewar wrote:
> > > [...some BM stuff...]
> > > you mean by "know better". If you mean do I know perfectly well that
> > > postconditions cannot capture this kind of specification, yes, I know
> > > that perfectly well -- many specifications and requirements cannot be
> > > formalized in any useful manner.
> 
> What's really odd here is that BM does not give the impression that he
> understands this point.  Go figure.

I think he does. I read a least one message in the last two days by BM
where he makes this point. Reiterating a point I have made else where.
In what cases does DBC detract from a solution?

> > But who should be resposible for the error message? You have a choice
> > between client of print and print itself.
> 
> Hint: it is not the dichotomy as you suggest.

OK, If I don't have a print system where I can have resposibility as a
client I have a problem. I must have DBC.  Now if you are saying that I
some cases I don't want to bother, which isn't an unreasonable in the
case of print, I agree. In this case a default handler makes sense, but
this is just being nice. You must be able to take the DBC route with the
client accepting responsibility.

> > The answer must be the client, because as the client, I may want to
> > handle errors in different ways. Pop up a window, or print to a console
> > window as two reasonable examples.
> 
> That's not the point.  The point is, what is expressed via the
> _mechanisms_ you suggest.  This latter depends largely on the context
> of who/what is using the system (client and print together).

-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-21  0:00                                                       ` Jon S Anthony
@ 1997-08-22  0:00                                                         ` Nick Leaton
  1997-08-23  0:00                                                           ` Ken Garlington
  0 siblings, 1 reply; 255+ messages in thread
From: Nick Leaton @ 1997-08-22  0:00 UTC (permalink / raw)



Jon S Anthony wrote:
> 
> In article <33FAB35A.18AA15BB@calfp.co.uk> Nick Leaton <nickle@calfp.co.uk> writes:
> 
> > > To demonstrate the problem, attempt to encode the critical Ariane 5
> > > assumption as a "top-level abstract class." It is not directly
> > > representable
> > > as code, even as a "top-level" abstraction.
> >
> > But neither are any of the specs you have for a fighter
> 
> That's OK, Ken is not the one claiming that this can be done.  Meyer
> and the E-Jihad are the ones making this fatuous claim.
> 
> > aircraft. Just as you have to decompose your code, you have to
> > decompose you assertions or specifications. Just because you can't
> > write 'fly plane' and be done with it in Eiffel (or Ada) it doesn't
> > make DBC wrong.
> 
> Spoken like a true reductionist.  This is not a decomposition problem.
> I tried to point this out before when I spoke about how this problem
> is the direct analogue of the problem of "natural kinds" in knowlege
> representation.  You can't come up with contextually independent
> necessary and sufficient conditions for a definition for these things.
> But that is basically what you are trying to claim _is_ possible.

OK, so if you can't write such requirements in a rigorous way, how can
you write the application. If you can write an application that meets
the requirements, you can write a coded spec for the problem. In the
extreme case, the code for the application is the specification. If you
cannot code the spec/requirements you can't check that they work. Just
because you have a deficient spec, or because you cannot envision what a
set of DBC assertions are for a problem doesn't detract from DBC.



> > > Said another way, could you write "War and Peace" as a "top-level"
> > > abstraction?
> >
> > Ok.
> >
> > A hit B and made up.
> 
> Not even close, :-)


Unfortunately, it takes up more characters than 'War and Peace' !

-- 

Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-21  0:00                                                     ` Jon S Anthony
@ 1997-08-22  0:00                                                       ` Joachim Durchholz
  0 siblings, 0 replies; 255+ messages in thread
From: Joachim Durchholz @ 1997-08-22  0:00 UTC (permalink / raw)



Jon S Anthony wrote:
>
> In article <33FA3B0F.62780A5C@munich.netsurf.de> Joachim Durchholz
> <joachim.durchholz@munich.netsurf.de> writes:
>
> > Document non-executable stuff in comments. Have your documentation
> > generated automatically. No redundancy, documentation is easy to do
> > along with the formal specs (class interfaces) and/or the coding
> > (routines).
> 
> Sounds OK (note that the non-executable stuff is typically the most
> important in this sort of context).  Of course this is easily done in
> any language...

Well, I'd like to actually see it in any other language. The obstacles
seem to be:
- Ignorance (DBC is quite new, I've been aware of it since just 5
years...)
- No conventions how and where the assertions should be written
- No binary formats that retain the assertions (this goes from object
formats to CORBA)
- It is serious work to write a "flat-short" tool that scans the
inheritance hierarchy and extracts all contracts

Regards,
Joachim
-- 
Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-23  0:00                                     ` W. Wesley Groleau x4923
@ 1997-08-23  0:00                                       ` Robert Dewar
  0 siblings, 0 replies; 255+ messages in thread
From: Robert Dewar @ 1997-08-23  0:00 UTC (permalink / raw)



Wes says

<<If someone says X is obvious, when many people do not see X, then
someone doesn't define obvious the same way I do.....>>


That's not quite so simple an issue. The word obvious has to be defined
for a particular subset of people. What is obvious to nuclear engineers,
or for that matter to experts in automobile tire repair, may not be
obvious to me, but that does not mean the word is being used in a strange
way.

I think we all from time to time make the mistake of not defining clearly
what the domain is for the use of the word obvious. FOr example, there
are things about the definition of Ada at the RM level that are indeed
obvious to the ARG members, and others with this kind of exposure to the
RM, but not generally obvious, even to skilled programmers.

Consequently, the word obvious is probably better avoided, unless you are
very careful to say what the claimed domain is (I have been trying to
avoid using the O-word, even when things are quite O to me :-)





^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-21  0:00                                                 ` Joachim Durchholz
@ 1997-08-23  0:00                                                   ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-23  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:
> 
> The advantage of this being part of the language definition is that
> a) the conventions are the same for every shop (a mere comment
> convention might be different, creating incompatibilities not with the
> executable code but with the development environments)
> b) Eiffel can make use of executable assertions and compile them as
> run-time checks.
>
> [snip] 
>
> Eiffel assertions are not compiled if they take the form of a comment.

Then they aren't Eiffel assertions, per the definition you gave in (a)
and (b)!

> You can write something like
> 
>   feature sqrt (x: real): real is
>   require
>     nonnegative_argument: x >= 0
>   do
>     ... (lots of code omitted)
>   ensure
>     nonnegative_result: Result >= 0
>     maximum_precision: -- Every mantissa bit except the last is correct
>   end
> 
> The short tool will report this routine as
> 
>   feature sqrt (x: real): real is
>   require
>     nonnegative_argument: x >= 0
>   ensure
>     nonnegative_result: Result >= 0
>     maximum_precision: -- Every mantissa bit except the last is correct
>   end
> 
> so executable and non-executable assertions aren't handled any
> differently for documentation purposes.

Nor would they be handled any differently in Ada, etc.
To repeat: For those items in comments, what advantage does
Eiffel provide?

> 
> Regards,
> Joachim
> --
> Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-22  0:00                                                         ` Nick Leaton
@ 1997-08-23  0:00                                                           ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-23  0:00 UTC (permalink / raw)



Nick Leaton wrote:
> 
> OK, so if you can't write such requirements in a rigorous way, how can
> you write the application. If you can write an application that meets
> the requirements, you can write a coded spec for the problem. In the
> extreme case, the code for the application is the specification.

Welcome to the Ariane IV problem!

The code is an _implementation_ of the specification. Except for trivial
cases, it is not the _only_ implementation. Furthermore, the
specification
can state things not related to the implementation -- in particular, the
assumptions of the physical environment -- at a level that can be (a)
subjective and (b) non-implementable as code. The code still works,
since
it doesn't have to encode such assumptions.

> If you
> cannot code the spec/requirements you can't check that they work. Just
> because you have a deficient spec, or because you cannot envision what a
> set of DBC assertions are for a problem doesn't detract from DBC.

Being able to implement a spec, and being able to test the
implementation,
is not the same as saying that the code can replace the spec. This is
a lesson learned from Ariane. For more information, read my paper (or
the inquiry report, referenced from that paper).

> 
> --
> 
> Nick




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-21  0:00                                                     ` Joachim Durchholz
@ 1997-08-23  0:00                                                       ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-23  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:
> 
> Ken Garlington wrote:
> > > The issue is that DBC allows to integrate code and code
> > documentation
> > > better. It is possible to write top-level abstract classes that just
> > > encapsulate a few assertions; there is no need to duplicate these
> > > assertions in other documents, at Eiffel (at this level) is easy to
> > read
> > > even for a non-programmer.
> >
> > To demonstrate the problem, attempt to encode the critical Ariane 5
> > assumption as a "top-level abstract class." It is not directly
> > representable
> > as code, even as a "top-level" abstraction.
> >
> > Said another way, could you write "War and Peace" as a "top-level"
> > abstraction?
> 
> People keep mixing the documentation aspects and the run-time checking
> aspects of Eiffel assertions.
> 
> Assertions as documentation *need not be executable* (so there is no
> problem encoding the critical Ariane-5 conditions or even War and Peace
> as a precondition).
> Assertions for run-time checking must be executable, of course. But even
> these double up as documentation on the routine.
> 
> At its first stage, Design by Contract is just a discipline: write down
> the preconditions and postconditions of the routine. Make sure the
> preconditions and postconditions match what the routine does (easy, the
> assertions are in the vicinity anyway). Have them stand out clearly via
> keywords so that the "short" tool can create a documentation that
> contains the routine signature with their pre- and postconditions.
> 
> The next level is that some assertions may be executable. This allows
> run-time checking, and (more important) it encourages the programmer to
> actually make assertions and code consistent. Even the non-executable
> ones - anybody with some practice in getting the checkable assertions
> right will have no trouble putting down precise non-executable
> assertions.
> 
> > > > Again: You need to have experience in systems analysis and
> > > > requirements
> > > > capture to understand that the hard stuff is not readily
> > > > expressible in code.
> > >
> > > Eiffel assertions are *not* code. They are specifications for code.
> > >  Some of these specifications happen to be checkable at run-time,
> >
> > Read both of these statements carefully, several times.
> > That, coupled with the experiment I describe above, should demonstrate
> > the problem with your thinking.
> 
> They don't. Either you don't understand me, or I don't understand you.
> (BTW which two statements do you mean?)

Simple: You can't have it both ways, You claim that Eiffel assertions
are
superior because they're executable, while simultaneously claiming they
are
not executable code. Specifically (quoting you):

  1. "Eiffel assertions are *not* code. They are specifications for
code."
  2. "Some of these specifications happen to be checkable at
run-time..."

Which ever way you go, you have a downside by your own
arguments (executable assertions are limiting; non-executable ones can't
be tested during execution). You can't claim the advantages of each
without
also claiming the disadvantages. It's an interesting dance you're doing,
but you will bump into a wall whichever way you jump.

> 
> Regards,
> Joachim
> --
> Please don't send unsolicited ads.




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-21  0:00                                                   ` Don Harrison
@ 1997-08-23  0:00                                                     ` Ken Garlington
  0 siblings, 0 replies; 255+ messages in thread
From: Ken Garlington @ 1997-08-23  0:00 UTC (permalink / raw)



> Having said that, it's also true that verifiable specifications *do* get omitted
> from specifications, not because it's impossible to specify them, but because
> they're difficult to specify. Although some are unlikely to admit it, the Ariane
> profile thingo probably falls into that category.

Total nonsense. Flight envelopes can easily be specified, and usually
are.
They can also be tested. Read the inquiry report: The profile "thingo"
was
left out not because it was hard to specify, but because it (and the
corresponding validation) was thought to be _unnecessary_, since the
system was already in operation.

What would be difficult would be to write an assertion to capture the
flight envelope. This would require a model of the environment inside
the code. Such a model can be created in a laboratory and used to
validate a system, but it is difficult (not impossible, but difficult)
to build it into the system itself.

> 
> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-12  0:00                                   ` Don Harrison
  1997-08-12  0:00                                     ` Jon S Anthony
  1997-08-12  0:00                                     ` Ken Garlington
@ 1997-08-23  0:00                                     ` W. Wesley Groleau x4923
  1997-08-23  0:00                                       ` Robert Dewar
  2 siblings, 1 reply; 255+ messages in thread
From: W. Wesley Groleau x4923 @ 1997-08-23  0:00 UTC (permalink / raw)



> :Any time someone says something is obvious, without any evidence or
> :argument to support it, I pretty much assume that the point is ceded.

If someone says X is obvious, when many people do not see X, then
someone doesn't define obvious the same way I do.....




^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
@ 1997-08-24  0:00 Robert Dewar
  0 siblings, 0 replies; 255+ messages in thread
From: Robert Dewar @ 1997-08-24  0:00 UTC (permalink / raw)



Nick writes

<<> OK, so if you can't write such requirements in a rigorous way, how can
> you write the application. If you can write an application that meets
> the requirements, you can write a coded spec for the problem. In the
> extreme case, the code for the application is the specification.>>


Many people have made statements like this, but in my experience, this is
quite false. It is often the case that it is impossible to write down
requirements in a rigorous way, either because you don't know what they
are, or they are stated at a level of abstraction ("use a pleasing color
scheme, easy on the eyes, for the GUI") that is not susceptible to
formalization.

Sure, the code for the application is *a* specification of *something*, but
most likely it is *not* *the* desired specification.

This is often frustrating to those who want a nice clean theoretical
model that guarantees reliable code, but we need methods that can indeed
handle the more general case where we do not always have rigorous
specifications.

Note that the problem of not being able to create such specifications
is not restricted to hardware. Consider the two requirements that
were placed on the IBM Trackpoint before its release:

(a) On average, people must find it as easy to use out of the box as a
trackball, even if they have experience with a trackball.

(b) On average, people must find the trackpoint as easy to use as a mouse
given extensive practice with both.

These were taken very seriously, and the release of the product was
delayed until these requirements were met. But I don't see how you
could formalize these requirements into a form that would rigorously
tell you if your mechanical device met these requirements.

Once I heard Wirth state that one should simply refuse to attempt to
write a program in such circumstances. His point was that it was impossible
to guarantee correctness by the method he was proposing at the time 
(successive refinement, maintaining the invariant of correctness).
My response (that what we needed was reliability, not correctness, and
that correctness was only a tool to achieve reoliability), drew applause
from the audience, which was frustrated by this narrow view.

Things are not as simple as one might hope :-)







^ permalink raw reply	[flat|nested] 255+ messages in thread

* Re: Safety-critical development in Ada and Eiffel
  1997-08-19  0:00                                           ` Robert Dewar
                                                               ` (2 preceding siblings ...)
  1997-08-20  0:00                                             ` Ken Garlington
@ 1997-08-26  0:00                                             ` Richard A. O'Keefe
  3 siblings, 0 replies; 255+ messages in thread
From: Richard A. O'Keefe @ 1997-08-26  0:00 UTC (permalink / raw)



dewar@merv.cs.nyu.edu (Robert Dewar) writes:
>What should be the post condition after outputting an error message
>from a compiler?

>pragma Assert (programmer now understands what they did wrong);

>You need a *really* clever language to test that one (well I suppose the
>assertion routine executed at runtime could ask the programmer whether
>he understood :-)

That won't do as a postcondition for error messages.
One of my all-time favourite error messages came from the Burroughs
ESPOL compiler:

    "If you know what it means, implement it."

Such a message does not imply that the programmer did anything wrong at all.
(Although it _usually_ meant that.)

-- 
Four policemen playing jazz on an up escalator in the railway station.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.




^ permalink raw reply	[flat|nested] 255+ messages in thread

end of thread, other threads:[~1997-08-26  0:00 UTC | newest]

Thread overview: 255+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-07-18  0:00 Safety-critical development in Ada and Eiffel Marin David Condic, 561.796.8997, M/S 731-96
  -- strict thread matches above, loose matches on Subject: below --
1997-08-24  0:00 Robert Dewar
1997-07-24  0:00 Marin David Condic, 561.796.8997, M/S 731-96
1997-07-21  0:00 Marin David Condic, 561.796.8997, M/S 731-96
1997-07-21  0:00 ` Ken Garlington
1997-07-21  0:00 Marin David Condic, 561.796.8997, M/S 731-96
1997-07-21  0:00 ` Ken Garlington
1997-07-18  0:00 Marin David Condic, 561.796.8997, M/S 731-96
1997-07-18  0:00 Marin David Condic, 561.796.8997, M/S 731-96
1997-07-22  0:00 ` Karel Th�nissen
1997-07-18  0:00 Marin David Condic, 561.796.8997, M/S 731-96
1997-07-17  0:00 Marin David Condic, 561.796.8997, M/S 731-96
1997-07-17  0:00 ` Samuel Mize
1997-07-17  0:00   ` Ken Garlington
1997-07-09  0:00 Is ADA as good for graphics programming as C? (WAS: Re: Avoiding the second historic mistake) Tucker Taft
1997-07-10  0:00 ` Safety-critical development in Ada and Eiffel Don Harrison
1997-07-10  0:00   ` Joe Gwinn
1997-07-11  0:00     ` Robert S. White
1997-07-15  0:00       ` Don Harrison
1997-07-15  0:00         ` Ken Garlington
1997-07-16  0:00           ` Don Harrison
1997-07-10  0:00   ` Ken Garlington
1997-07-11  0:00     ` Ted Velkoff
1997-07-12  0:00       ` Ken Garlington
1997-07-13  0:00         ` Jon S Anthony
1997-07-14  0:00           ` Wes Groleau
1997-07-15  0:00             ` Jon S Anthony
1997-07-15  0:00           ` Don Harrison
1997-07-15  0:00             ` Ken Garlington
1997-07-16  0:00           ` Paul Johnson
1997-07-16  0:00             ` Ken Garlington
1997-07-17  0:00               ` Paul Johnson
1997-07-17  0:00                 ` Ken Garlington
1997-07-18  0:00                   ` Paul Johnson
1997-07-18  0:00                     ` Jon S Anthony
1997-07-18  0:00                     ` Ken Garlington
1997-07-21  0:00                       ` Paul Johnson
1997-07-17  0:00             ` Jon S Anthony
     [not found]               ` <EDHqKo.K52@world.std.com>
1997-07-18  0:00                 ` Jon S Anthony
1997-07-19  0:00                   ` Robert A Duff
1997-07-20  0:00                     ` Tucker Taft
1997-07-10  0:00   ` Mike Stark
1997-07-11  0:00     ` Donovan Baarda
1997-07-13  0:00       ` Steve Furlong
1997-07-16  0:00         ` Joachim Durchholz
1997-07-17  0:00           ` Ken Garlington
1997-07-17  0:00           ` Robert Dewar
1997-07-18  0:00           ` John Nagle
1997-07-18  0:00             ` Jon S Anthony
1997-07-18  0:00           ` Jon S Anthony
1997-07-18  0:00             ` Nick Leaton
1997-07-18  0:00               ` Jon S Anthony
1997-07-11  0:00   ` Kazimir Majorinc
1997-07-12  0:00     ` Ken Garlington
1997-07-11  0:00   ` Don Harrison
1997-07-11  0:00     ` James Graves
1997-07-14  0:00       ` Don Harrison
1997-07-12  0:00     ` Ken Garlington
1997-07-15  0:00       ` Don Harrison
1997-07-15  0:00         ` Wes Groleau
1997-07-15  0:00           ` Ken Garlington
1997-07-16  0:00           ` Don Harrison
1997-07-16  0:00             ` Ken Garlington
1997-07-16  0:00               ` Robert Dewar
1997-07-17  0:00                 ` Paul Johnson
1997-07-17  0:00                   ` Jon S Anthony
1997-07-17  0:00                   ` Stuart Palin
1997-07-18  0:00                     ` Ian Rae
1997-07-18  0:00                     ` Paul Johnson
1997-07-18  0:00                   ` Joachim Durchholz
1997-07-18  0:00                 ` Don Harrison
1997-07-20  0:00                 ` Don Harrison
1997-07-18  0:00           ` Robert I. Eachus
1997-07-21  0:00             ` W. Wesley Groleau x4923
1997-07-15  0:00         ` Ken Garlington
1997-07-16  0:00           ` Jean-Marc Jezequel
1997-07-16  0:00             ` Ken Garlington
1997-07-17  0:00               ` "Paul E. Bennett"
1997-07-17  0:00                 ` Robert Dewar
1997-07-17  0:00           ` Joachim Durchholz
1997-07-19  0:00             ` Ken Garlington
1997-07-21  0:00             ` Robert S. White
1997-07-20  0:00               ` nabbasi
1997-07-21  0:00                 ` W. Wesley Groleau x4923
1997-07-18  0:00           ` Don Harrison
1997-07-18  0:00             ` Ken Garlington
1997-07-22  0:00               ` Don Harrison
1997-07-21  0:00                 ` Ken Garlington
1997-07-23  0:00                   ` Don Harrison
1997-07-23  0:00                     ` Ken Garlington
1997-07-25  0:00                       ` Don Harrison
1997-07-23  0:00                     ` W. Wesley Groleau x4923
1997-07-24  0:00                       ` Don Harrison
1997-07-24  0:00                         ` Ken Garlington
1997-07-26  0:00                           ` Joachim Durchholz
1997-07-31  0:00                             ` Ken Garlington
1997-07-28  0:00                           ` Nick Leaton
1997-07-28  0:00                             ` Steve Jones - JON
1997-07-31  0:00                             ` Ken Garlington
1997-07-29  0:00                           ` Don Harrison
1997-07-31  0:00                             ` Ken Garlington
1997-08-07  0:00                               ` Don Harrison
1997-08-07  0:00                                 ` Ken Garlington
1997-08-09  0:00                                   ` Jim Cochrane
1997-08-11  0:00                                     ` Paul Johnson
1997-08-11  0:00                                       ` Ken Garlington
1997-08-12  0:00                                         ` Mark A Biggar
1997-08-19  0:00                                           ` Robert Dewar
1997-08-19  0:00                                             ` Bertrand Meyer
1997-08-19  0:00                                               ` Robert Dewar
1997-08-20  0:00                                                 ` Nick Leaton
1997-08-21  0:00                                                   ` Jon S Anthony
1997-08-22  0:00                                                     ` Nick Leaton
1997-08-21  0:00                                                   ` Joachim Durchholz
1997-08-20  0:00                                                 ` Lee Webber
1997-08-21  0:00                                                   ` Don Harrison
1997-08-23  0:00                                                     ` Ken Garlington
1997-08-19  0:00                                             ` Nick Leaton
1997-08-20  0:00                                             ` Ken Garlington
1997-08-26  0:00                                             ` Richard A. O'Keefe
1997-08-13  0:00                                         ` Paul Johnson
1997-08-13  0:00                                           ` Ken Garlington
1997-08-15  0:00                                             ` Paul Johnson
1997-08-15  0:00                                               ` Ken Garlington
1997-08-18  0:00                                                 ` Joachim Durchholz
1997-08-19  0:00                                                   ` Ken Garlington
1997-08-20  0:00                                                     ` Nick Leaton
1997-08-20  0:00                                                       ` Nasser
1997-08-21  0:00                                                       ` Jon S Anthony
1997-08-22  0:00                                                         ` Nick Leaton
1997-08-23  0:00                                                           ` Ken Garlington
1997-08-21  0:00                                                     ` Joachim Durchholz
1997-08-23  0:00                                                       ` Ken Garlington
1997-08-12  0:00                                   ` Don Harrison
1997-08-12  0:00                                     ` Jon S Anthony
1997-08-13  0:00                                       ` Ted Velkoff
1997-08-13  0:00                                         ` Jon S Anthony
1997-08-13  0:00                                         ` Ken Garlington
1997-08-13  0:00                                           ` Ted Velkoff
1997-08-14  0:00                                             ` Matt Austern
1997-08-14  0:00                                               ` Ted Velkoff
1997-08-18  0:00                                                 ` Matt Austern
1997-08-20  0:00                                                   ` Joachim Durchholz
1997-08-21  0:00                                                     ` Jon S Anthony
1997-08-22  0:00                                                       ` Joachim Durchholz
1997-08-15  0:00                                             ` Ken Garlington
1997-08-16  0:00                                               ` Ted Velkoff
1997-08-16  0:00                                                 ` Ken Garlington
1997-08-16  0:00                                                   ` Jon S Anthony
1997-08-16  0:00                                                     ` Ken Garlington
1997-08-18  0:00                                                     ` Ted Velkoff
1997-08-18  0:00                                                   ` Ted Velkoff
1997-08-19  0:00                                                     ` Ken Garlington
1997-08-14  0:00                                           ` Nick Leaton
1997-08-16  0:00                                             ` Robert Dewar
1997-08-18  0:00                                             ` Joachim Durchholz
1997-08-19  0:00                                               ` Ken Garlington
1997-08-21  0:00                                                 ` Joachim Durchholz
1997-08-23  0:00                                                   ` Ken Garlington
1997-08-13  0:00                                       ` Don Harrison
1997-08-13  0:00                                         ` Jon S Anthony
1997-08-15  0:00                                           ` Don Harrison
1997-08-16  0:00                                             ` Jon S Anthony
1997-08-13  0:00                                         ` Samuel Mize
1997-08-13  0:00                                           ` Robert A Duff
1997-08-14  0:00                                             ` Jon S Anthony
1997-08-15  0:00                                             ` Don Harrison
1997-08-16  0:00                                               ` Ken Garlington
1997-08-12  0:00                                     ` Ken Garlington
1997-08-23  0:00                                     ` W. Wesley Groleau x4923
1997-08-23  0:00                                       ` Robert Dewar
1997-07-16  0:00         ` Warwick Pulley
1997-07-16  0:00           ` Nick Leaton
1997-07-16  0:00             ` Robert Dewar
1997-07-20  0:00               ` Joachim Durchholz
1997-07-24  0:00                 ` Joe Buck
1997-07-24  0:00                 ` Paul M Gover
1997-07-26  0:00                   ` Joachim Durchholz
1997-07-28  0:00                     ` Robert S. White
1997-08-09  0:00                       ` Marinos J. Yannikos
1997-08-10  0:00                         ` Robert S. White
1997-08-11  0:00                         ` Peter Hamer
1997-08-11  0:00                           ` "Paul E. Bennett"
1997-07-29  0:00                     ` Don Harrison
1997-07-21  0:00               ` Don Harrison
1997-07-17  0:00             ` Warwick Pulley
1997-07-17  0:00               ` Warwick Pulley
1997-07-17  0:00               ` Nick Leaton
1997-07-17  0:00                 ` Richie Bielak
1997-07-17  0:00                   ` Ken Garlington
1997-07-23  0:00                     ` Don Harrison
1997-07-23  0:00                       ` Ken Garlington
1997-07-25  0:00                         ` Don Harrison
1997-07-17  0:00                   ` Karel Th�nissen
1997-07-17  0:00                   ` Samuel Tardieu
1997-07-17  0:00                     ` Richie Bielak
1997-07-23  0:00                       ` Don Harrison
1997-07-23  0:00                         ` Jon S Anthony
1997-07-24  0:00                           ` Don Harrison
1997-07-24  0:00                             ` Jon S Anthony
1997-07-23  0:00                         ` Ken Garlington
1997-07-25  0:00                           ` Don Harrison
1997-07-23  0:00                         ` Karel Th�nissen
1997-07-24  0:00                           ` Don Harrison
1997-07-24  0:00                             ` Ken Garlington
1997-07-29  0:00                               ` Don Harrison
1997-07-29  0:00                                 ` Ron Kohl
1997-07-29  0:00                                   ` Don Harrison
1997-07-30  0:00                                     ` Don Harrison
1997-07-31  0:00                                 ` Ken Garlington
1997-08-07  0:00                                   ` Don Harrison
1997-08-07  0:00                                     ` Ken Garlington
1997-08-13  0:00                                       ` Don Harrison
1997-08-13  0:00                                         ` Ken Garlington
1997-08-14  0:00                                           ` Don Harrison
1997-08-15  0:00                                             ` Ken Garlington
1997-08-19  0:00                                               ` Don Harrison
1997-08-19  0:00                                                 ` Lee Webber
1997-08-20  0:00                                                 ` Ken Garlington
1997-08-21  0:00                                                   ` Don Harrison
1997-08-15  0:00                                             ` Don Harrison
1997-08-15  0:00                                               ` Ken Garlington
1997-08-16  0:00                                                 ` Jon S Anthony
1997-08-19  0:00                                                 ` Don Harrison
1997-08-20  0:00                                                   ` Ken Garlington
1997-08-15  0:00                                             ` Lee Webber
1997-08-19  0:00                                               ` Don Harrison
1997-08-19  0:00                                                 ` Lee Webber
1997-07-24  0:00                             ` Don Harrison
1997-07-23  0:00                   ` Don Harrison
1997-07-23  0:00                     ` Ken Garlington
1997-07-25  0:00                       ` Don Harrison
1997-07-17  0:00                 ` Ken Garlington
     [not found]                 ` <JSA.97Jul17174044@alexandria.organon.com>
1997-07-18  0:00                   ` Nick Leaton
1997-07-18  0:00                   ` Joachim Durchholz
1997-07-17  0:00           ` Don Harrison
1997-07-17  0:00             ` Karel Th�nissen
1997-07-21  0:00               ` Don Harrison
1997-07-17  0:00             ` Robert Dewar
1997-07-22  0:00               ` Don Harrison
1997-07-17  0:00             ` Robert Dewar
1997-07-18  0:00               ` Jon S Anthony
1997-07-19  0:00                 ` Robert A Duff
1997-07-21  0:00                   ` W. Wesley Groleau x4923
1997-07-21  0:00               ` Don Harrison
1997-07-21  0:00                 ` Jon S Anthony
1997-07-21  0:00                   ` Brian Rogoff
1997-07-16  0:00     ` Alan Brain
1997-07-18  0:00       ` Don Harrison
1997-07-22  0:00         ` Alan Brain
1997-07-22  0:00           ` Don Harrison
1997-07-23  0:00             ` Jon S Anthony
1997-07-24  0:00               ` Don Harrison
1997-07-25  0:00               ` Alan Brain
1997-07-25  0:00                 ` Jon S Anthony
1997-07-11  0:00   ` Don Harrison

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox